mirror of
https://github.com/zoriya/flood.git
synced 2025-12-05 23:06:20 +00:00
style: add new rule for imports (#785)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"extends": ["plugin:@typescript-eslint/recommended", "prettier"],
|
||||
"plugins": ["simple-import-sort", "n"],
|
||||
|
||||
"parserOptions": {
|
||||
"project": "./tsconfig.json"
|
||||
@@ -11,6 +12,9 @@
|
||||
},
|
||||
|
||||
"rules": {
|
||||
"n/prefer-node-protocol": "error",
|
||||
"simple-import-sort/imports": "error",
|
||||
"simple-import-sort/exports": "error",
|
||||
"import/no-extraneous-dependencies": 0,
|
||||
"no-underscore-dangle": ["error", {"allow": ["_id"]}],
|
||||
"@typescript-eslint/lines-between-class-members": ["error", "always", {"exceptAfterSingleLine": true}],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const path = require('path');
|
||||
const path = require('node:path');
|
||||
const ESLintPlugin = require('eslint-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const autoprefixer = require('autoprefixer');
|
||||
const path = require('path');
|
||||
const path = require('node:path');
|
||||
const webpack = require('webpack');
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
|
||||
@@ -13,7 +13,7 @@ const webpack = require('webpack');
|
||||
const WebpackDevServer = require('webpack-dev-server');
|
||||
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
|
||||
const {choosePort, prepareUrls} = require('react-dev-utils/WebpackDevServerUtils');
|
||||
const path = require('path');
|
||||
const path = require('node:path');
|
||||
const paths = require('../../shared/config/paths');
|
||||
const config = require('../config/webpack.config.dev');
|
||||
|
||||
|
||||
17
config.ts
17
config.ts
@@ -1,14 +1,13 @@
|
||||
import {spawn} from 'child_process';
|
||||
import crypto from 'crypto';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import yargs from 'yargs/yargs';
|
||||
import {spawn} from 'node:child_process';
|
||||
import crypto from 'node:crypto';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
import {configSchema} from '@shared/schema/Config';
|
||||
|
||||
import type {Config} from '@shared/schema/Config';
|
||||
import type {ClientConnectionSettings} from '@shared/schema/ClientConnectionSettings';
|
||||
import type {Config} from '@shared/schema/Config';
|
||||
import {configSchema} from '@shared/schema/Config';
|
||||
import yargs from 'yargs/yargs';
|
||||
|
||||
import {version} from './package.json';
|
||||
|
||||
|
||||
@@ -144,6 +144,8 @@
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
"eslint-import-resolver-webpack": "^0.13.2",
|
||||
"eslint-plugin-n": "^17.10.2",
|
||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||
"eslint-webpack-plugin": "^3.2.0",
|
||||
"express": "^4.18.2",
|
||||
"express-rate-limit": "^6.7.0",
|
||||
|
||||
71
pnpm-lock.yaml
generated
71
pnpm-lock.yaml
generated
@@ -242,6 +242,12 @@ importers:
|
||||
eslint-import-resolver-webpack:
|
||||
specifier: ^0.13.2
|
||||
version: 0.13.8(eslint-plugin-import@2.29.1)(webpack@5.93.0(esbuild@0.19.12))
|
||||
eslint-plugin-n:
|
||||
specifier: ^17.10.2
|
||||
version: 17.10.2(eslint@8.57.0)
|
||||
eslint-plugin-simple-import-sort:
|
||||
specifier: ^12.1.1
|
||||
version: 12.1.1(eslint@8.57.0)
|
||||
eslint-webpack-plugin:
|
||||
specifier: ^3.2.0
|
||||
version: 3.2.0(eslint@8.57.0)(webpack@5.93.0(esbuild@0.19.12))
|
||||
@@ -3573,6 +3579,12 @@ packages:
|
||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
eslint-compat-utils@0.5.1:
|
||||
resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
eslint: '>=6.0.0'
|
||||
|
||||
eslint-config-airbnb-base@15.0.0:
|
||||
resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==}
|
||||
engines: {node: ^10.12.0 || >=12.0.0}
|
||||
@@ -3645,6 +3657,12 @@ packages:
|
||||
eslint-import-resolver-webpack:
|
||||
optional: true
|
||||
|
||||
eslint-plugin-es-x@7.8.0:
|
||||
resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
eslint: '>=8'
|
||||
|
||||
eslint-plugin-flowtype@8.0.3:
|
||||
resolution: {integrity: sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
@@ -3682,6 +3700,12 @@ packages:
|
||||
peerDependencies:
|
||||
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
|
||||
|
||||
eslint-plugin-n@17.10.2:
|
||||
resolution: {integrity: sha512-e+s4eAf5NtJaxPhTNu3qMO0Iz40WANS93w9LQgYcvuljgvDmWi/a3rh+OrNyMHeng6aOWGJO0rCg5lH4zi8yTw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: '>=8.23.0'
|
||||
|
||||
eslint-plugin-react-hooks@4.6.2:
|
||||
resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -3694,6 +3718,11 @@ packages:
|
||||
peerDependencies:
|
||||
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7
|
||||
|
||||
eslint-plugin-simple-import-sort@12.1.1:
|
||||
resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==}
|
||||
peerDependencies:
|
||||
eslint: '>=5.0.0'
|
||||
|
||||
eslint-plugin-testing-library@5.11.1:
|
||||
resolution: {integrity: sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6'}
|
||||
@@ -4118,6 +4147,10 @@ packages:
|
||||
resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
globals@15.9.0:
|
||||
resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
globalthis@1.0.4:
|
||||
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -5068,6 +5101,10 @@ packages:
|
||||
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minimist@1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
|
||||
@@ -10515,6 +10552,11 @@ snapshots:
|
||||
|
||||
escape-string-regexp@4.0.0: {}
|
||||
|
||||
eslint-compat-utils@0.5.1(eslint@8.57.0):
|
||||
dependencies:
|
||||
eslint: 8.57.0
|
||||
semver: 7.6.3
|
||||
|
||||
eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.0.4))(eslint-import-resolver-webpack@0.13.8)(eslint@8.57.0))(eslint@8.57.0):
|
||||
dependencies:
|
||||
confusing-browser-globals: 1.0.11
|
||||
@@ -10611,6 +10653,13 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint-plugin-es-x@7.8.0(eslint@8.57.0):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
|
||||
'@eslint-community/regexpp': 4.11.0
|
||||
eslint: 8.57.0
|
||||
eslint-compat-utils: 0.5.1(eslint@8.57.0)
|
||||
|
||||
eslint-plugin-flowtype@8.0.3(@babel/plugin-syntax-flow@7.24.7(@babel/core@7.25.2))(@babel/plugin-transform-react-jsx@7.25.2(@babel/core@7.25.2))(eslint@8.57.0):
|
||||
dependencies:
|
||||
'@babel/plugin-syntax-flow': 7.24.7(@babel/core@7.25.2)
|
||||
@@ -10677,6 +10726,18 @@ snapshots:
|
||||
safe-regex-test: 1.0.3
|
||||
string.prototype.includes: 2.0.0
|
||||
|
||||
eslint-plugin-n@17.10.2(eslint@8.57.0):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
|
||||
enhanced-resolve: 5.17.1
|
||||
eslint: 8.57.0
|
||||
eslint-plugin-es-x: 7.8.0(eslint@8.57.0)
|
||||
get-tsconfig: 4.7.6
|
||||
globals: 15.9.0
|
||||
ignore: 5.3.1
|
||||
minimatch: 9.0.5
|
||||
semver: 7.6.3
|
||||
|
||||
eslint-plugin-react-hooks@4.6.2(eslint@8.57.0):
|
||||
dependencies:
|
||||
eslint: 8.57.0
|
||||
@@ -10703,6 +10764,10 @@ snapshots:
|
||||
string.prototype.matchall: 4.0.11
|
||||
string.prototype.repeat: 1.0.0
|
||||
|
||||
eslint-plugin-simple-import-sort@12.1.1(eslint@8.57.0):
|
||||
dependencies:
|
||||
eslint: 8.57.0
|
||||
|
||||
eslint-plugin-testing-library@5.11.1(eslint@8.57.0)(typescript@5.0.4):
|
||||
dependencies:
|
||||
'@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.0.4)
|
||||
@@ -11238,6 +11303,8 @@ snapshots:
|
||||
dependencies:
|
||||
type-fest: 0.20.2
|
||||
|
||||
globals@15.9.0: {}
|
||||
|
||||
globalthis@1.0.4:
|
||||
dependencies:
|
||||
define-properties: 1.2.1
|
||||
@@ -12345,6 +12412,10 @@ snapshots:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
||||
minimist@1.2.8: {}
|
||||
|
||||
minipass@7.1.2: {}
|
||||
|
||||
@@ -9,7 +9,7 @@ process.on('unhandledRejection', (err) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
const path = require('path');
|
||||
const path = require('node:path');
|
||||
const esbuild = require('esbuild');
|
||||
const chalk = require('chalk');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
const chalk = require('chalk');
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const {spawn} = require('child_process');
|
||||
const crypto = require('node:crypto');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const {spawn} = require('node:child_process');
|
||||
|
||||
const temporaryRuntimeDirectory = path.resolve(os.tmpdir(), `flood.test.${crypto.randomBytes(12).toString('hex')}`);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import {appDist} from '../../shared/config/paths';
|
||||
import config from '../../config';
|
||||
import {appDist} from '../../shared/config/paths';
|
||||
|
||||
const staticAssets = [path.join(appDist, 'index.html')];
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import {AccessLevel} from '../../../shared/schema/constants/Auth';
|
||||
import Users from '../../models/Users';
|
||||
|
||||
import type {Credentials} from '../../../shared/schema/Auth';
|
||||
import type {RTorrentConnectionSettings} from '../../../shared/schema/ClientConnectionSettings';
|
||||
import {AccessLevel} from '../../../shared/schema/constants/Auth';
|
||||
import Users from '../../models/Users';
|
||||
import type {UserInDatabase1} from './types/UserInDatabase1';
|
||||
|
||||
const migrationError = (err?: Error) => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import path from 'node:path';
|
||||
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
|
||||
import config from '../../../config';
|
||||
import Users from '../../models/Users';
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import chalk from 'chalk';
|
||||
import fastify from 'fastify';
|
||||
import fs from 'fs';
|
||||
import fs from 'node:fs';
|
||||
import type {Server} from 'node:http';
|
||||
import type {Http2SecureServer} from 'node:http2';
|
||||
|
||||
import chalk from 'chalk';
|
||||
import type {FastifyInstance} from 'fastify';
|
||||
import type {Http2SecureServer} from 'http2';
|
||||
import type {Server} from 'http';
|
||||
import fastify from 'fastify';
|
||||
|
||||
import config from '../../config';
|
||||
import constructRoutes from '../routes';
|
||||
import packageJSON from '../../package.json';
|
||||
import constructRoutes from '../routes';
|
||||
|
||||
const startWebServer = async () => {
|
||||
const {ssl = false, floodServerHost: host, floodServerPort: port} = config;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import type {Request, Response, NextFunction} from 'express';
|
||||
|
||||
import {getAllServices} from '../services';
|
||||
import type {NextFunction, Request, Response} from 'express';
|
||||
|
||||
import type {ServiceInstances} from '../services';
|
||||
import {getAllServices} from '../services';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import type {EventMap} from 'typed-emitter';
|
||||
import type {Operation} from 'fast-json-patch';
|
||||
import type {Request, Response} from 'express';
|
||||
import type {Operation} from 'fast-json-patch';
|
||||
import type {EventMap} from 'typed-emitter';
|
||||
import type TypedEmitter from 'typed-emitter';
|
||||
|
||||
import DiskUsage from '../models/DiskUsage';
|
||||
import {getAllServices} from '../services';
|
||||
import ServerEvent from '../models/ServerEvent';
|
||||
|
||||
import type {DiskUsageSummary} from '../models/DiskUsage';
|
||||
import type {TransferHistory} from '../../shared/types/TransferData';
|
||||
import type {DiskUsageSummary} from '../models/DiskUsage';
|
||||
import DiskUsage from '../models/DiskUsage';
|
||||
import ServerEvent from '../models/ServerEvent';
|
||||
import {getAllServices} from '../services';
|
||||
|
||||
export default async (req: Request, res: Response) => {
|
||||
const {user} = req;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type {Request, Response, NextFunction} from 'express';
|
||||
import type {NextFunction, Request, Response} from 'express';
|
||||
|
||||
export default (req: Request, res: Response, next: NextFunction) => {
|
||||
req.socket.setKeepAlive(true);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type {Request, Response, NextFunction} from 'express';
|
||||
import type {NextFunction, Request, Response} from 'express';
|
||||
|
||||
import {AccessLevel} from '../../shared/schema/constants/Auth';
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import {EventEmitter} from 'events';
|
||||
import type TypedEmitter from 'typed-emitter';
|
||||
import {EventEmitter} from 'node:events';
|
||||
|
||||
import type {Disks} from '@shared/types/DiskUsage';
|
||||
|
||||
import {isPlatformSupported, diskUsage} from '../util/diskUsageUtil';
|
||||
import type TypedEmitter from 'typed-emitter';
|
||||
|
||||
import type {SupportedPlatform} from '../util/diskUsageUtil';
|
||||
import {diskUsage, isPlatformSupported} from '../util/diskUsageUtil';
|
||||
|
||||
export interface DiskUsageSummary {
|
||||
id: number;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type {TransferData, TransferSnapshot} from '@shared/types/TransferData';
|
||||
import {setInterval} from 'node:timers';
|
||||
|
||||
import Datastore from '@seald-io/nedb';
|
||||
import {setInterval} from 'timers';
|
||||
import type {TransferData, TransferSnapshot} from '@shared/types/TransferData';
|
||||
|
||||
import config from '../../config';
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type {Response} from 'express';
|
||||
|
||||
import type {ServerEvents} from '@shared/types/ServerEvents';
|
||||
import type {Response} from 'express';
|
||||
|
||||
class ServerEvent {
|
||||
res: Response;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import config from '../../config';
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import {argon2id, argon2Verify} from 'hash-wasm';
|
||||
import crypto from 'crypto';
|
||||
import crypto from 'node:crypto';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import Datastore from '@seald-io/nedb';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import {argon2id, argon2Verify} from 'hash-wasm';
|
||||
|
||||
import {AccessLevel} from '../../shared/schema/constants/Auth';
|
||||
import config from '../../config';
|
||||
import {bootstrapServicesForUser, destroyUserServices} from '../services';
|
||||
|
||||
import type {ClientConnectionSettings} from '../../shared/schema/ClientConnectionSettings';
|
||||
import type {Credentials, UserInDatabase} from '../../shared/schema/Auth';
|
||||
import type {ClientConnectionSettings} from '../../shared/schema/ClientConnectionSettings';
|
||||
import {AccessLevel} from '../../shared/schema/constants/Auth';
|
||||
import {bootstrapServicesForUser, destroyUserServices} from '../services';
|
||||
|
||||
const hashPassword = async (password: string): Promise<string> => {
|
||||
return argon2id({
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import crypto from 'crypto';
|
||||
import crypto from 'node:crypto';
|
||||
|
||||
import fastify from 'fastify';
|
||||
import supertest from 'supertest';
|
||||
|
||||
import {AccessLevel} from '../../../shared/schema/constants/Auth';
|
||||
|
||||
import constructRoutes from '..';
|
||||
import {getAuthToken} from '../../util/authUtil';
|
||||
|
||||
import type {
|
||||
AuthRegistrationOptions,
|
||||
AuthUpdateUserOptions,
|
||||
AuthVerificationResponse,
|
||||
} from '../../../shared/schema/api/auth';
|
||||
import type {ClientConnectionSettings} from '../../../shared/schema/ClientConnectionSettings';
|
||||
import {AccessLevel} from '../../../shared/schema/constants/Auth';
|
||||
import {getAuthToken} from '../../util/authUtil';
|
||||
import constructRoutes from '..';
|
||||
|
||||
const testConnectionSettings: ClientConnectionSettings = {
|
||||
client: 'rTorrent',
|
||||
|
||||
@@ -1,21 +1,9 @@
|
||||
import express from 'express';
|
||||
import passport from 'passport';
|
||||
import rateLimit from 'express-rate-limit';
|
||||
|
||||
import type {Response} from 'express';
|
||||
import express from 'express';
|
||||
import rateLimit from 'express-rate-limit';
|
||||
import passport from 'passport';
|
||||
|
||||
import {
|
||||
authAuthenticationSchema,
|
||||
authRegistrationSchema,
|
||||
authUpdateUserSchema,
|
||||
AuthVerificationPreloadConfigs,
|
||||
} from '../../../shared/schema/api/auth';
|
||||
import {bootstrapServicesForUser, destroyUserServices} from '../../services';
|
||||
import config from '../../../config';
|
||||
import {getAuthToken, getCookieOptions} from '../../util/authUtil';
|
||||
import requireAdmin from '../../middleware/requireAdmin';
|
||||
import Users from '../../models/Users';
|
||||
|
||||
import type {
|
||||
AuthAuthenticationOptions,
|
||||
AuthAuthenticationResponse,
|
||||
@@ -23,7 +11,17 @@ import type {
|
||||
AuthUpdateUserOptions,
|
||||
AuthVerificationResponse,
|
||||
} from '../../../shared/schema/api/auth';
|
||||
import {
|
||||
authAuthenticationSchema,
|
||||
authRegistrationSchema,
|
||||
authUpdateUserSchema,
|
||||
AuthVerificationPreloadConfigs,
|
||||
} from '../../../shared/schema/api/auth';
|
||||
import type {Credentials, UserInDatabase} from '../../../shared/schema/Auth';
|
||||
import requireAdmin from '../../middleware/requireAdmin';
|
||||
import Users from '../../models/Users';
|
||||
import {bootstrapServicesForUser, destroyUserServices} from '../../services';
|
||||
import {getAuthToken, getCookieOptions} from '../../util/authUtil';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import fastify from 'fastify';
|
||||
import supertest from 'supertest';
|
||||
|
||||
import constructRoutes from '..';
|
||||
import {getAuthToken} from '../../util/authUtil';
|
||||
|
||||
import type {ClientSettings} from '../../../shared/types/ClientSettings';
|
||||
import {getAuthToken} from '../../util/authUtil';
|
||||
import constructRoutes from '..';
|
||||
|
||||
const app = fastify({disableRequestLogging: true, logger: true});
|
||||
let request: supertest.SuperTest<supertest.Test>;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import express, {Response} from 'express';
|
||||
|
||||
import type {ClientSettings} from '@shared/types/ClientSettings';
|
||||
import type {SetClientSettingsOptions} from '@shared/types/api/client';
|
||||
import type {ClientSettings} from '@shared/types/ClientSettings';
|
||||
import express, {Response} from 'express';
|
||||
|
||||
import requireAdmin from '../../middleware/requireAdmin';
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import fastify from 'fastify';
|
||||
import fs from 'fs';
|
||||
import supertest from 'supertest';
|
||||
import fs from 'node:fs';
|
||||
|
||||
import constructRoutes from '..';
|
||||
import {getAuthToken} from '../../util/authUtil';
|
||||
import {getTempPath} from '../../models/TemporaryStorage';
|
||||
import fastify from 'fastify';
|
||||
import supertest from 'supertest';
|
||||
|
||||
import type {AddFeedOptions, AddRuleOptions, ModifyFeedOptions} from '../../../shared/types/api/feed-monitor';
|
||||
import type {Feed, Rule} from '../../../shared/types/Feed';
|
||||
import {getTempPath} from '../../models/TemporaryStorage';
|
||||
import {getAuthToken} from '../../util/authUtil';
|
||||
import constructRoutes from '..';
|
||||
|
||||
const app = fastify({disableRequestLogging: true, logger: false});
|
||||
let request: supertest.SuperTest<supertest.Test>;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import express, {Response} from 'express';
|
||||
|
||||
import type {AddFeedOptions, AddRuleOptions, ModifyFeedOptions} from '@shared/types/api/feed-monitor';
|
||||
import express, {Response} from 'express';
|
||||
|
||||
import {accessDeniedError, isAllowedPath, sanitizePath} from '../../util/fileUtil';
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import fastify from 'fastify';
|
||||
import supertest from 'supertest';
|
||||
|
||||
import constructRoutes from '..';
|
||||
import {getAuthToken} from '../../util/authUtil';
|
||||
|
||||
import type {FloodSettings} from '../../../shared/types/FloodSettings';
|
||||
import {getAuthToken} from '../../util/authUtil';
|
||||
import constructRoutes from '..';
|
||||
|
||||
const app = fastify({disableRequestLogging: true, logger: false});
|
||||
let request: supertest.SuperTest<supertest.Test>;
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
import express, {Response} from 'express';
|
||||
import fs from 'fs';
|
||||
import passport from 'passport';
|
||||
import path from 'path';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import {contentTokenSchema} from '@shared/schema/api/torrents';
|
||||
|
||||
import type {DirectoryListQuery, DirectoryListResponse, SetFloodSettingsOptions} from '@shared/types/api/index';
|
||||
import type {FloodSettings} from '@shared/types/FloodSettings';
|
||||
import type {NotificationFetchOptions, NotificationState} from '@shared/types/Notification';
|
||||
import type {DirectoryListQuery, DirectoryListResponse, SetFloodSettingsOptions} from '@shared/types/api/index';
|
||||
import express, {Response} from 'express';
|
||||
import passport from 'passport';
|
||||
|
||||
import {accessDeniedError, isAllowedPath, sanitizePath} from '../../util/fileUtil';
|
||||
import appendUserServices from '../../middleware/appendUserServices';
|
||||
import authRoutes from './auth';
|
||||
import clientRoutes from './client';
|
||||
import clientActivityStream from '../../middleware/clientActivityStream';
|
||||
import eventStream from '../../middleware/eventStream';
|
||||
import feedMonitorRoutes from './feed-monitor';
|
||||
import {getAuthToken, verifyToken} from '../../util/authUtil';
|
||||
import torrentsRoutes from './torrents';
|
||||
import {accessDeniedError, isAllowedPath, sanitizePath} from '../../util/fileUtil';
|
||||
import {rateLimit} from '../utils';
|
||||
import authRoutes from './auth';
|
||||
import clientRoutes from './client';
|
||||
import feedMonitorRoutes from './feed-monitor';
|
||||
import torrentsRoutes from './torrents';
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
import crypto from 'crypto';
|
||||
import fastify from 'fastify';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import readline from 'readline';
|
||||
import stream from 'stream';
|
||||
import supertest from 'supertest';
|
||||
import crypto from 'node:crypto';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import readline from 'node:readline';
|
||||
import stream from 'node:stream';
|
||||
|
||||
import axios from 'axios';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import fastify from 'fastify';
|
||||
import supertest from 'supertest';
|
||||
|
||||
import constructRoutes from '..';
|
||||
import {getAuthToken} from '../../util/authUtil';
|
||||
import {getTempPath} from '../../models/TemporaryStorage';
|
||||
import paths from '../../../shared/config/paths';
|
||||
|
||||
import type {TorrentStatus} from '../../../shared/constants/torrentStatusMap';
|
||||
import type {AddTorrentByFileOptions, AddTorrentByURLOptions} from '../../../shared/schema/api/torrents';
|
||||
import type {MoveTorrentsOptions, SetTorrentsTrackersOptions} from '../../../shared/types/api/torrents';
|
||||
import type {TorrentContent} from '../../../shared/types/TorrentContent';
|
||||
import type {TorrentList} from '../../../shared/types/Torrent';
|
||||
import type {TorrentStatus} from '../../../shared/constants/torrentStatusMap';
|
||||
import type {TorrentContent} from '../../../shared/types/TorrentContent';
|
||||
import type {TorrentTracker} from '../../../shared/types/TorrentTracker';
|
||||
import {getTempPath} from '../../models/TemporaryStorage';
|
||||
import {getAuthToken} from '../../util/authUtil';
|
||||
import constructRoutes from '..';
|
||||
|
||||
const app = fastify({bodyLimit: 100 * 1024 * 1024 * 1024, disableRequestLogging: true, forceCloseConnections: true});
|
||||
let request: supertest.SuperTest<supertest.Test>;
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import childProcess from 'child_process';
|
||||
import contentDisposition from 'content-disposition';
|
||||
import createTorrent from 'create-torrent';
|
||||
import express, {Response} from 'express';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import sanitize from 'sanitize-filename';
|
||||
import tar, {Pack} from 'tar-fs';
|
||||
import childProcess from 'node:child_process';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import type {
|
||||
AddTorrentByFileOptions,
|
||||
@@ -27,6 +22,11 @@ import type {
|
||||
StartTorrentsOptions,
|
||||
StopTorrentsOptions,
|
||||
} from '@shared/types/api/torrents';
|
||||
import contentDisposition from 'content-disposition';
|
||||
import createTorrent from 'create-torrent';
|
||||
import express, {Response} from 'express';
|
||||
import sanitize from 'sanitize-filename';
|
||||
import tar, {Pack} from 'tar-fs';
|
||||
|
||||
import {
|
||||
addTorrentByFileSchema,
|
||||
@@ -34,6 +34,9 @@ import {
|
||||
reannounceTorrentsSchema,
|
||||
setTorrentsTagsSchema,
|
||||
} from '../../../shared/schema/api/torrents';
|
||||
import {getTempPath} from '../../models/TemporaryStorage';
|
||||
import {asyncFilter} from '../../util/async';
|
||||
import {getToken} from '../../util/authUtil';
|
||||
import {
|
||||
accessDeniedError,
|
||||
existAsync,
|
||||
@@ -42,9 +45,6 @@ import {
|
||||
isAllowedPathAsync,
|
||||
sanitizePath,
|
||||
} from '../../util/fileUtil';
|
||||
import {getTempPath} from '../../models/TemporaryStorage';
|
||||
import {getToken} from '../../util/authUtil';
|
||||
import {asyncFilter} from '../../util/async';
|
||||
import {rateLimit} from '../utils';
|
||||
|
||||
const getDestination = async (
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import type {FastifyInstance} from 'fastify';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import fastifyCompress from '@fastify/compress';
|
||||
import {fastifyExpress} from '@fastify/express';
|
||||
import fastifyStatic from '@fastify/static';
|
||||
import paths from '@shared/config/paths';
|
||||
import {Strategy} from 'passport-jwt';
|
||||
|
||||
import apiRoutes from './api';
|
||||
import config from '../../config';
|
||||
import Users from '../models/Users';
|
||||
import {authTokenSchema, UserInDatabase} from '@shared/schema/Auth';
|
||||
import express from 'express';
|
||||
import morgan from 'morgan';
|
||||
import passport from 'passport';
|
||||
import bodyParser from 'body-parser';
|
||||
import cookieParser from 'cookie-parser';
|
||||
import {fastifyExpress} from '@fastify/express';
|
||||
import fastifyCompress from '@fastify/compress';
|
||||
import fastifyStatic from '@fastify/static';
|
||||
import express from 'express';
|
||||
import type {FastifyInstance} from 'fastify';
|
||||
import morgan from 'morgan';
|
||||
import passport from 'passport';
|
||||
import {Strategy} from 'passport-jwt';
|
||||
|
||||
import config from '../../config';
|
||||
import Users from '../models/Users';
|
||||
import apiRoutes from './api';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import config from '../../config';
|
||||
|
||||
import expressRateLimit, {Options} from 'express-rate-limit';
|
||||
import {RequestHandler} from 'express';
|
||||
import expressRateLimit, {Options} from 'express-rate-limit';
|
||||
|
||||
import config from '../../config';
|
||||
|
||||
export function rateLimit(passedOptions?: Partial<Options>): RequestHandler {
|
||||
if (config.disableRateLimit) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {EventEmitter} from 'events';
|
||||
import type {EventMap} from 'typed-emitter';
|
||||
import type TypedEmitter from 'typed-emitter';
|
||||
import {EventEmitter} from 'node:events';
|
||||
|
||||
import type {UserInDatabase} from '@shared/schema/Auth';
|
||||
import type {EventMap} from 'typed-emitter';
|
||||
import type TypedEmitter from 'typed-emitter';
|
||||
|
||||
import type {ServiceInstances} from '.';
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import {homedir} from 'os';
|
||||
import path from 'path';
|
||||
|
||||
import {TorrentContentPriority} from '@shared/types/TorrentContent';
|
||||
import {TorrentTrackerType} from '@shared/types/TorrentTracker';
|
||||
import {homedir} from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
import type {
|
||||
AddTorrentByFileOptions,
|
||||
@@ -10,6 +7,8 @@ import type {
|
||||
ReannounceTorrentsOptions,
|
||||
SetTorrentsTagsOptions,
|
||||
} from '@shared/schema/api/torrents';
|
||||
import type {DelugeConnectionSettings} from '@shared/schema/ClientConnectionSettings';
|
||||
import type {SetClientSettingsOptions} from '@shared/types/api/client';
|
||||
import type {
|
||||
CheckTorrentsOptions,
|
||||
DeleteTorrentsOptions,
|
||||
@@ -23,20 +22,19 @@ import type {
|
||||
StopTorrentsOptions,
|
||||
} from '@shared/types/api/torrents';
|
||||
import type {ClientSettings} from '@shared/types/ClientSettings';
|
||||
import type {DelugeConnectionSettings} from '@shared/schema/ClientConnectionSettings';
|
||||
import type {TorrentContent} from '@shared/types/TorrentContent';
|
||||
import type {TorrentList, TorrentListSummary, TorrentProperties} from '@shared/types/Torrent';
|
||||
import type {TorrentContent} from '@shared/types/TorrentContent';
|
||||
import {TorrentContentPriority} from '@shared/types/TorrentContent';
|
||||
import type {TorrentPeer} from '@shared/types/TorrentPeer';
|
||||
import type {TorrentTracker} from '@shared/types/TorrentTracker';
|
||||
import {TorrentTrackerType} from '@shared/types/TorrentTracker';
|
||||
import type {TransferSummary} from '@shared/types/TransferData';
|
||||
import type {SetClientSettingsOptions} from '@shared/types/api/client';
|
||||
|
||||
import {fetchUrls} from '../../util/fetchUtil';
|
||||
import {getTorrentStatusFromStatuses} from './util/torrentPropertiesUtil';
|
||||
|
||||
import ClientGatewayService from '../clientGatewayService';
|
||||
import ClientRequestManager from './clientRequestManager';
|
||||
import {DelugeCoreTorrentFilePriority} from './types/DelugeCoreMethods';
|
||||
import {getTorrentStatusFromStatuses} from './util/torrentPropertiesUtil';
|
||||
|
||||
class DelugeClientGatewayService extends ClientGatewayService {
|
||||
private clientRequestManager = new ClientRequestManager(this.user.client as DelugeConnectionSettings);
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import {deflate, inflate} from 'zlib';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import tls from 'tls';
|
||||
|
||||
import {decode, encode} from './util/rencode';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import tls from 'node:tls';
|
||||
import {deflate, inflate} from 'node:zlib';
|
||||
|
||||
import type {DelugeConnectionSettings} from '@shared/schema/ClientConnectionSettings';
|
||||
|
||||
import type {RencodableArray, RencodableData, RencodableObject} from './util/rencode';
|
||||
|
||||
import type {
|
||||
DelugeCorePreferences,
|
||||
DelugeCoreSessionStatuses,
|
||||
@@ -17,6 +13,8 @@ import type {
|
||||
DelugeCoreTorrentStatuses,
|
||||
DelugeCoreTorrentTracker,
|
||||
} from './types/DelugeCoreMethods';
|
||||
import type {RencodableArray, RencodableData, RencodableObject} from './util/rencode';
|
||||
import {decode, encode} from './util/rencode';
|
||||
|
||||
const DELUGE_RPC_PROTOCOL_VERSION = 0x01;
|
||||
const protocolVerBuf = Buffer.alloc(1);
|
||||
|
||||
@@ -451,4 +451,4 @@ function loads(data: Buffer, decodeUTF8 = true): RencodableData {
|
||||
return decode(new Buff(data), decodeUTF8);
|
||||
}
|
||||
|
||||
export {dumps as encode, dumps, loads as decode, loads};
|
||||
export {loads as decode, dumps, dumps as encode, loads};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
|
||||
import type {
|
||||
AddTorrentByFileOptions,
|
||||
@@ -6,6 +6,8 @@ import type {
|
||||
ReannounceTorrentsOptions,
|
||||
SetTorrentsTagsOptions,
|
||||
} from '@shared/schema/api/torrents';
|
||||
import type {TransmissionConnectionSettings} from '@shared/schema/ClientConnectionSettings';
|
||||
import type {SetClientSettingsOptions} from '@shared/types/api/client';
|
||||
import type {
|
||||
CheckTorrentsOptions,
|
||||
DeleteTorrentsOptions,
|
||||
@@ -17,24 +19,22 @@ import type {
|
||||
StopTorrentsOptions,
|
||||
} from '@shared/types/api/torrents';
|
||||
import type {ClientSettings} from '@shared/types/ClientSettings';
|
||||
import type {TorrentContent} from '@shared/types/TorrentContent';
|
||||
import type {TorrentList, TorrentListSummary, TorrentProperties} from '@shared/types/Torrent';
|
||||
import type {TorrentContent} from '@shared/types/TorrentContent';
|
||||
import type {TorrentPeer} from '@shared/types/TorrentPeer';
|
||||
import type {TorrentTracker} from '@shared/types/TorrentTracker';
|
||||
import type {TransferSummary} from '@shared/types/TransferData';
|
||||
import type {TransmissionConnectionSettings} from '@shared/schema/ClientConnectionSettings';
|
||||
import type {SetClientSettingsOptions} from '@shared/types/api/client';
|
||||
|
||||
import * as geoip from '../geoip';
|
||||
import ClientGatewayService from '../clientGatewayService';
|
||||
import ClientRequestManager from './clientRequestManager';
|
||||
import {TorrentPriority} from '../../../shared/types/Torrent';
|
||||
import {TorrentContentPriority} from '../../../shared/types/TorrentContent';
|
||||
import {TorrentTrackerType} from '../../../shared/types/TorrentTracker';
|
||||
import {fetchUrls} from '../../util/fetchUtil';
|
||||
import {getDomainsFromURLs} from '../../util/torrentPropertiesUtil';
|
||||
import {TorrentContentPriority} from '../../../shared/types/TorrentContent';
|
||||
import {TorrentPriority} from '../../../shared/types/Torrent';
|
||||
import torrentPropertiesUtil from './util/torrentPropertiesUtil';
|
||||
import {TorrentTrackerType} from '../../../shared/types/TorrentTracker';
|
||||
import ClientGatewayService from '../clientGatewayService';
|
||||
import * as geoip from '../geoip';
|
||||
import ClientRequestManager from './clientRequestManager';
|
||||
import {TransmissionPriority, TransmissionTorrentsSetArguments} from './types/TransmissionTorrentsMethods';
|
||||
import torrentPropertiesUtil from './util/torrentPropertiesUtil';
|
||||
|
||||
class TransmissionClientGatewayService extends ClientGatewayService {
|
||||
clientRequestManager = new ClientRequestManager(this.user.client as TransmissionConnectionSettings);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import axios, {AxiosError} from 'axios';
|
||||
|
||||
import type {TransmissionConnectionSettings} from '@shared/schema/ClientConnectionSettings';
|
||||
import axios, {AxiosError} from 'axios';
|
||||
|
||||
import type {
|
||||
TransmissionSessionGetArguments,
|
||||
@@ -9,9 +8,9 @@ import type {
|
||||
TransmissionSessionStats,
|
||||
} from './types/TransmissionSessionMethods';
|
||||
import {
|
||||
TransmissionTorrentAddArguments,
|
||||
TransmissionTorrentIDs,
|
||||
TransmissionTorrentProperties,
|
||||
TransmissionTorrentAddArguments,
|
||||
TransmissionTorrentsGetArguments,
|
||||
TransmissionTorrentsRemoveArguments,
|
||||
TransmissionTorrentsSetArguments,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {TransmissionTorrentError, TransmissionTorrentStatus} from '../types/TransmissionTorrentsMethods';
|
||||
|
||||
import type {TorrentProperties} from '../../../../shared/types/Torrent';
|
||||
import type {TransmissionTorrentProperties} from '../types/TransmissionTorrentsMethods';
|
||||
import {TransmissionTorrentError, TransmissionTorrentStatus} from '../types/TransmissionTorrentsMethods';
|
||||
|
||||
const getTorrentStatus = (
|
||||
properties: Pick<
|
||||
|
||||
@@ -4,6 +4,8 @@ import type {
|
||||
ReannounceTorrentsOptions,
|
||||
SetTorrentsTagsOptions,
|
||||
} from '@shared/schema/api/torrents';
|
||||
import type {UserInDatabase} from '@shared/schema/Auth';
|
||||
import type {SetClientSettingsOptions} from '@shared/types/api/client';
|
||||
import type {
|
||||
CheckTorrentsOptions,
|
||||
DeleteTorrentsOptions,
|
||||
@@ -17,16 +19,14 @@ import type {
|
||||
StopTorrentsOptions,
|
||||
} from '@shared/types/api/torrents';
|
||||
import type {ClientSettings} from '@shared/types/ClientSettings';
|
||||
import type {SetClientSettingsOptions} from '@shared/types/api/client';
|
||||
import type {TorrentContent} from '@shared/types/TorrentContent';
|
||||
import type {TorrentListSummary, TorrentProperties} from '@shared/types/Torrent';
|
||||
import type {TorrentContent} from '@shared/types/TorrentContent';
|
||||
import type {TorrentPeer} from '@shared/types/TorrentPeer';
|
||||
import type {TorrentTracker} from '@shared/types/TorrentTracker';
|
||||
import type {TransferSummary} from '@shared/types/TransferData';
|
||||
import type {UserInDatabase} from '@shared/schema/Auth';
|
||||
|
||||
import BaseService from './BaseService';
|
||||
import config from '../../config';
|
||||
import BaseService from './BaseService';
|
||||
|
||||
type ClientGatewayServiceEvents = {
|
||||
CLIENT_CONNECTION_STATE_CHANGE: (isConnected: boolean) => void;
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import path from 'path';
|
||||
import Datastore from '@seald-io/nedb';
|
||||
import path from 'node:path';
|
||||
|
||||
import Datastore from '@seald-io/nedb';
|
||||
import type {FeedItem} from 'feedsub';
|
||||
|
||||
import BaseService from './BaseService';
|
||||
import config from '../../config';
|
||||
import FeedReader from '../models/FeedReader';
|
||||
import {getFeedItemsMatchingRules, getTorrentUrlsFromFeedItem} from '../util/feedUtil';
|
||||
|
||||
import type {AddFeedOptions, AddRuleOptions, ModifyFeedOptions} from '../../shared/types/api/feed-monitor';
|
||||
import type {Feed, Item, MatchedTorrents, Rule} from '../../shared/types/Feed';
|
||||
import type {FeedReaderOptions} from '../models/FeedReader';
|
||||
import FeedReader from '../models/FeedReader';
|
||||
import {getFeedItemsMatchingRules, getTorrentUrlsFromFeedItem} from '../util/feedUtil';
|
||||
import BaseService from './BaseService';
|
||||
|
||||
class FeedService extends BaseService<Record<string, never>> {
|
||||
rules: Record<string, Array<Rule>> = {};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type {TransferHistory, TransferSummary} from '@shared/types/TransferData';
|
||||
|
||||
import BaseService from './BaseService';
|
||||
import config from '../../config';
|
||||
import HistoryEra from '../models/HistoryEra';
|
||||
import BaseService from './BaseService';
|
||||
|
||||
type HistoryServiceEvents = {
|
||||
TRANSFER_SUMMARY_FULL_UPDATE: (payload: {id: number; summary: TransferSummary}) => void;
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import type {UserInDatabase} from '@shared/schema/Auth';
|
||||
|
||||
import ClientGatewayService from './clientGatewayService';
|
||||
import DelugeClientGatewayService from './Deluge/clientGatewayService';
|
||||
import FeedService from './feedService';
|
||||
import HistoryService from './historyService';
|
||||
import NotificationService from './notificationService';
|
||||
import QBittorrentClientGatewayService from './qBittorrent/clientGatewayService';
|
||||
import RTorrentClientGatewayService from './rTorrent/clientGatewayService';
|
||||
import SettingService from './settingService';
|
||||
import TaxonomyService from './taxonomyService';
|
||||
import TorrentService from './torrentService';
|
||||
|
||||
import DelugeClientGatewayService from './Deluge/clientGatewayService';
|
||||
import QBittorrentClientGatewayService from './qBittorrent/clientGatewayService';
|
||||
import RTorrentClientGatewayService from './rTorrent/clientGatewayService';
|
||||
import TransmissionClientGatewayService from './Transmission/clientGatewayService';
|
||||
|
||||
export interface ServiceInstances {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Datastore from '@seald-io/nedb';
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
|
||||
import Datastore from '@seald-io/nedb';
|
||||
import type {
|
||||
Notification,
|
||||
NotificationCount,
|
||||
@@ -8,8 +8,8 @@ import type {
|
||||
NotificationState,
|
||||
} from '@shared/types/Notification';
|
||||
|
||||
import BaseService from './BaseService';
|
||||
import config from '../../config';
|
||||
import BaseService from './BaseService';
|
||||
|
||||
type NotificationServiceEvents = {
|
||||
NOTIFICATION_COUNT_CHANGE: (payload: {id: number; data: NotificationCount}) => void;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import fs from 'fs';
|
||||
import {homedir} from 'os';
|
||||
import parseTorrent from 'parse-torrent';
|
||||
import path from 'path';
|
||||
import fs from 'node:fs';
|
||||
import {homedir} from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
import type {
|
||||
AddTorrentByFileOptions,
|
||||
@@ -9,6 +8,8 @@ import type {
|
||||
ReannounceTorrentsOptions,
|
||||
SetTorrentsTagsOptions,
|
||||
} from '@shared/schema/api/torrents';
|
||||
import type {QBittorrentConnectionSettings} from '@shared/schema/ClientConnectionSettings';
|
||||
import type {SetClientSettingsOptions} from '@shared/types/api/client';
|
||||
import type {
|
||||
CheckTorrentsOptions,
|
||||
DeleteTorrentsOptions,
|
||||
@@ -22,27 +23,26 @@ import type {
|
||||
StopTorrentsOptions,
|
||||
} from '@shared/types/api/torrents';
|
||||
import type {ClientSettings} from '@shared/types/ClientSettings';
|
||||
import type {QBittorrentConnectionSettings} from '@shared/schema/ClientConnectionSettings';
|
||||
import type {TorrentContent} from '@shared/types/TorrentContent';
|
||||
import type {TorrentList, TorrentListSummary, TorrentProperties} from '@shared/types/Torrent';
|
||||
import type {TorrentContent} from '@shared/types/TorrentContent';
|
||||
import type {TorrentPeer} from '@shared/types/TorrentPeer';
|
||||
import type {TorrentTracker} from '@shared/types/TorrentTracker';
|
||||
import type {TransferSummary} from '@shared/types/TransferData';
|
||||
import type {SetClientSettingsOptions} from '@shared/types/api/client';
|
||||
import parseTorrent from 'parse-torrent';
|
||||
|
||||
import ClientGatewayService from '../clientGatewayService';
|
||||
import ClientRequestManager from './clientRequestManager';
|
||||
import {TorrentPriority} from '../../../shared/types/Torrent';
|
||||
import {TorrentContentPriority} from '../../../shared/types/TorrentContent';
|
||||
import {TorrentTrackerType} from '../../../shared/types/TorrentTracker';
|
||||
import {fetchUrls} from '../../util/fetchUtil';
|
||||
import {getDomainsFromURLs} from '../../util/torrentPropertiesUtil';
|
||||
import ClientGatewayService from '../clientGatewayService';
|
||||
import ClientRequestManager from './clientRequestManager';
|
||||
import {QBittorrentTorrentContentPriority, QBittorrentTorrentTrackerStatus} from './types/QBittorrentTorrentsMethods';
|
||||
import {
|
||||
getTorrentPeerPropertiesFromFlags,
|
||||
getTorrentStatusFromState,
|
||||
getTorrentTrackerTypeFromURL,
|
||||
} from './util/torrentPropertiesUtil';
|
||||
import {QBittorrentTorrentContentPriority, QBittorrentTorrentTrackerStatus} from './types/QBittorrentTorrentsMethods';
|
||||
import {TorrentContentPriority} from '../../../shared/types/TorrentContent';
|
||||
import {TorrentPriority} from '../../../shared/types/Torrent';
|
||||
import {TorrentTrackerType} from '../../../shared/types/TorrentTracker';
|
||||
|
||||
class QBittorrentClientGatewayService extends ClientGatewayService {
|
||||
private clientRequestManager = new ClientRequestManager(this.user.client as QBittorrentConnectionSettings);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import axios from 'axios';
|
||||
import FormData from 'form-data';
|
||||
import {URLSearchParams} from 'url';
|
||||
import {URLSearchParams} from 'node:url';
|
||||
|
||||
import type {QBittorrentConnectionSettings} from '@shared/schema/ClientConnectionSettings';
|
||||
import axios from 'axios';
|
||||
import FormData from 'form-data';
|
||||
|
||||
import type {QBittorrentAppPreferences} from './types/QBittorrentAppMethods';
|
||||
import type {
|
||||
@@ -11,7 +11,6 @@ import type {
|
||||
QBittorrentSyncTorrentPeers,
|
||||
QBittorrentTorrentPeers,
|
||||
} from './types/QBittorrentSyncMethods';
|
||||
import type {QBittorrentTransferInfo} from './types/QBittorrentTransferMethods';
|
||||
import type {
|
||||
QBittorrentTorrentContentPriority,
|
||||
QBittorrentTorrentContents,
|
||||
@@ -20,6 +19,7 @@ import type {
|
||||
QBittorrentTorrentsAddOptions,
|
||||
QBittorrentTorrentTrackers,
|
||||
} from './types/QBittorrentTorrentsMethods';
|
||||
import type {QBittorrentTransferInfo} from './types/QBittorrentTransferMethods';
|
||||
|
||||
const EMPTY_SERVER_STATE = {
|
||||
dl_info_speed: 0,
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import {TorrentPeer} from '../../../../shared/types/TorrentPeer';
|
||||
import {TorrentTrackerType} from '../../../../shared/types/TorrentTracker';
|
||||
|
||||
import type {QBittorrentTorrentState} from '../types/QBittorrentTorrentsMethods';
|
||||
import type {TorrentProperties} from '../../../../shared/types/Torrent';
|
||||
import {TorrentPeer} from '../../../../shared/types/TorrentPeer';
|
||||
import type {TorrentTracker} from '../../../../shared/types/TorrentTracker';
|
||||
import {TorrentTrackerType} from '../../../../shared/types/TorrentTracker';
|
||||
import type {QBittorrentTorrentState} from '../types/QBittorrentTorrentsMethods';
|
||||
|
||||
export const getTorrentPeerPropertiesFromFlags = (flags: string): Pick<TorrentPeer, 'isEncrypted' | 'isIncoming'> => {
|
||||
const flagsArray = flags.split(' ');
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import fs from 'fs';
|
||||
import {move} from 'fs-extra';
|
||||
import path from 'path';
|
||||
import sanitize from 'sanitize-filename';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import type {
|
||||
AddTorrentByFileOptions,
|
||||
@@ -9,6 +7,8 @@ import type {
|
||||
ReannounceTorrentsOptions,
|
||||
SetTorrentsTagsOptions,
|
||||
} from '@shared/schema/api/torrents';
|
||||
import type {RTorrentConnectionSettings} from '@shared/schema/ClientConnectionSettings';
|
||||
import type {SetClientSettingsOptions} from '@shared/types/api/client';
|
||||
import type {
|
||||
CheckTorrentsOptions,
|
||||
DeleteTorrentsOptions,
|
||||
@@ -22,28 +22,20 @@ import type {
|
||||
StopTorrentsOptions,
|
||||
} from '@shared/types/api/torrents';
|
||||
import type {ClientSettings} from '@shared/types/ClientSettings';
|
||||
import type {RTorrentConnectionSettings} from '@shared/schema/ClientConnectionSettings';
|
||||
import type {TorrentContent} from '@shared/types/TorrentContent';
|
||||
import type {TorrentList, TorrentListSummary, TorrentProperties} from '@shared/types/Torrent';
|
||||
import type {TorrentContent} from '@shared/types/TorrentContent';
|
||||
import type {TorrentPeer} from '@shared/types/TorrentPeer';
|
||||
import type {TorrentTracker} from '@shared/types/TorrentTracker';
|
||||
import type {TransferSummary} from '@shared/types/TransferData';
|
||||
import type {SetClientSettingsOptions} from '@shared/types/api/client';
|
||||
import {move} from 'fs-extra';
|
||||
import sanitize from 'sanitize-filename';
|
||||
|
||||
import * as geoip from '../geoip';
|
||||
import {isAllowedPath, sanitizePath} from '../../util/fileUtil';
|
||||
import ClientGatewayService from '../clientGatewayService';
|
||||
import ClientRequestManager from './clientRequestManager';
|
||||
import {fetchUrls} from '../../util/fetchUtil';
|
||||
import {getMethodCalls, processMethodCallResponse} from './util/rTorrentMethodCallUtil';
|
||||
import {isAllowedPath, sanitizePath} from '../../util/fileUtil';
|
||||
import {getComment, setCompleted, setTrackers} from '../../util/torrentFileUtil';
|
||||
import {
|
||||
encodeTags,
|
||||
getAddTorrentPropertiesCalls,
|
||||
getTorrentETAFromProperties,
|
||||
getTorrentPercentCompleteFromProperties,
|
||||
getTorrentStatusFromProperties,
|
||||
} from './util/torrentPropertiesUtil';
|
||||
import ClientGatewayService from '../clientGatewayService';
|
||||
import * as geoip from '../geoip';
|
||||
import ClientRequestManager from './clientRequestManager';
|
||||
import {
|
||||
clientSettingMethodCallConfigs,
|
||||
torrentContentMethodCallConfigs,
|
||||
@@ -52,9 +44,16 @@ import {
|
||||
torrentTrackerMethodCallConfigs,
|
||||
transferSummaryMethodCallConfigs,
|
||||
} from './constants/methodCallConfigs';
|
||||
|
||||
import type {MultiMethodCalls} from './util/rTorrentMethodCallUtil';
|
||||
import type {RPCError} from './types/RPCError';
|
||||
import type {MultiMethodCalls} from './util/rTorrentMethodCallUtil';
|
||||
import {getMethodCalls, processMethodCallResponse} from './util/rTorrentMethodCallUtil';
|
||||
import {
|
||||
encodeTags,
|
||||
getAddTorrentPropertiesCalls,
|
||||
getTorrentETAFromProperties,
|
||||
getTorrentPercentCompleteFromProperties,
|
||||
getTorrentStatusFromProperties,
|
||||
} from './util/torrentPropertiesUtil';
|
||||
|
||||
class RTorrentClientGatewayService extends ClientGatewayService {
|
||||
clientRequestManager = new ClientRequestManager(this.user.client as RTorrentConnectionSettings);
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import type {NetConnectOpts} from 'net';
|
||||
import type {NetConnectOpts} from 'node:net';
|
||||
|
||||
import type {RTorrentConnectionSettings} from '@shared/schema/ClientConnectionSettings';
|
||||
|
||||
import {methodCallJSON, methodCallXML} from './util/scgiUtil';
|
||||
import {sanitizePath} from '../../util/fileUtil';
|
||||
|
||||
import type {MultiMethodCalls} from './util/rTorrentMethodCallUtil';
|
||||
import PQueue from 'p-queue';
|
||||
|
||||
import {sanitizePath} from '../../util/fileUtil';
|
||||
import type {MultiMethodCalls} from './util/rTorrentMethodCallUtil';
|
||||
import {methodCallJSON, methodCallXML} from './util/scgiUtil';
|
||||
|
||||
type MethodCallParameters = Array<string | Buffer | MultiMethodCalls>;
|
||||
|
||||
class ClientRequestManager {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {stringTransformer, numberTransformer} from '../../util/rTorrentMethodCallUtil';
|
||||
import {numberTransformer, stringTransformer} from '../../util/rTorrentMethodCallUtil';
|
||||
|
||||
const torrentContentMethodCallConfigs = {
|
||||
path: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {getDomainsFromURLs} from '../../../../util/torrentPropertiesUtil';
|
||||
import {stringTransformer, booleanTransformer, numberTransformer} from '../../util/rTorrentMethodCallUtil';
|
||||
import {booleanTransformer, numberTransformer, stringTransformer} from '../../util/rTorrentMethodCallUtil';
|
||||
|
||||
const torrentListMethodCallConfigs = {
|
||||
hash: {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {stringTransformer, booleanTransformer, numberTransformer} from '../../util/rTorrentMethodCallUtil';
|
||||
import {booleanTransformer, numberTransformer, stringTransformer} from '../../util/rTorrentMethodCallUtil';
|
||||
|
||||
const torrentPeerMethodCallConfigs = {
|
||||
address: {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import net from 'net';
|
||||
import net from 'node:net';
|
||||
|
||||
import deserializer from './XMLRPCDeserializer';
|
||||
import serializer from './XMLRPCSerializer';
|
||||
import {RPCError} from '../types/RPCError';
|
||||
|
||||
import type {MultiMethodCalls} from './rTorrentMethodCallUtil';
|
||||
import deserializer from './XMLRPCDeserializer';
|
||||
import type {XMLRPCValue} from './XMLRPCSerializer';
|
||||
import serializer from './XMLRPCSerializer';
|
||||
|
||||
const NULL_CHAR = String.fromCharCode(0);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import truncateTo from './numberUtils';
|
||||
|
||||
import type {TorrentStatus} from '@shared/constants/torrentStatusMap';
|
||||
import type {AddTorrentByFileOptions} from '@shared/schema/api/torrents';
|
||||
import type {TorrentProperties} from '@shared/types/Torrent';
|
||||
import type {TorrentStatus} from '@shared/constants/torrentStatusMap';
|
||||
|
||||
import truncateTo from './numberUtils';
|
||||
|
||||
export const getTorrentETAFromProperties = (
|
||||
processingTorrentProperties: Record<string, unknown>,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Datastore from '@seald-io/nedb';
|
||||
import path from 'path';
|
||||
import path from 'node:path';
|
||||
|
||||
import Datastore from '@seald-io/nedb';
|
||||
import type {FloodSettings} from '@shared/types/FloodSettings';
|
||||
|
||||
import config from '../../config';
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import jsonpatch, {Operation} from 'fast-json-patch';
|
||||
|
||||
import BaseService from './BaseService';
|
||||
import torrentStatusMap from '../../shared/constants/torrentStatusMap';
|
||||
|
||||
import type {Taxonomy} from '../../shared/types/Taxonomy';
|
||||
import type {TorrentStatus} from '../../shared/constants/torrentStatusMap';
|
||||
import type {TorrentProperties, TorrentList} from '../../shared/types/Torrent';
|
||||
import torrentStatusMap from '../../shared/constants/torrentStatusMap';
|
||||
import type {Taxonomy} from '../../shared/types/Taxonomy';
|
||||
import type {TorrentList, TorrentProperties} from '../../shared/types/Torrent';
|
||||
import BaseService from './BaseService';
|
||||
|
||||
type TaxonomyServiceEvents = {
|
||||
TAXONOMY_DIFF_CHANGE: (payload: {id: number; diff: Operation[]}) => void;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import type {TorrentListSummary, TorrentProperties} from '@shared/types/Torrent';
|
||||
import jsonpatch, {Operation} from 'fast-json-patch';
|
||||
|
||||
import type {TorrentProperties, TorrentListSummary} from '@shared/types/Torrent';
|
||||
|
||||
import BaseService from './BaseService';
|
||||
import config from '../../config';
|
||||
import {hasTorrentFinished} from '../util/torrentPropertiesUtil';
|
||||
import BaseService from './BaseService';
|
||||
|
||||
type TorrentServiceEvents = {
|
||||
FETCH_TORRENT_LIST_SUCCESS: () => void;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import type {AuthToken} from '@shared/schema/Auth';
|
||||
import {CookieOptions} from 'express';
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
import type {AuthToken} from '@shared/schema/Auth';
|
||||
|
||||
import config from '../../config';
|
||||
|
||||
const EXPIRATION_SECONDS = 60 * 60 * 24 * 7; // one week
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {spawn, SpawnOptions} from 'child_process';
|
||||
import {spawn, SpawnOptions} from 'node:child_process';
|
||||
|
||||
import type {Disk} from '@shared/types/DiskUsage';
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import type {FeedItem} from 'feedsub';
|
||||
|
||||
import {cdata as matchCDATA} from '../../shared/util/regEx';
|
||||
|
||||
import type {AddTorrentByURLOptions} from '../../shared/schema/api/torrents';
|
||||
import type {Rule} from '../../shared/types/Feed';
|
||||
import {cdata as matchCDATA} from '../../shared/util/regEx';
|
||||
|
||||
interface PendingDownloadItems
|
||||
extends Required<Pick<AddTorrentByURLOptions, 'urls' | 'destination' | 'tags' | 'start'>> {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import axios, {AxiosError} from 'axios';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import {isAllowedPath} from './fileUtil';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from 'fs';
|
||||
import {promises as fsp} from 'fs';
|
||||
import {homedir} from 'os';
|
||||
import path from 'path';
|
||||
import fs from 'node:fs';
|
||||
import {promises as fsp} from 'node:fs';
|
||||
import {homedir} from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
import config from '../../config';
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import bencode from 'bencode';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
import {LibTorrentFilePriority} from '../../shared/types/TorrentFile';
|
||||
import bencode from 'bencode';
|
||||
|
||||
import type {LibTorrentResume, RTorrentFile, TorrentFile} from '../../shared/types/TorrentFile';
|
||||
import {LibTorrentFilePriority} from '../../shared/types/TorrentFile';
|
||||
|
||||
const openAndDecodeTorrent = async (torrentPath: string): Promise<TorrentFile | null> => {
|
||||
let torrentData: TorrentFile | null = null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
// Make sure any symlinks in the project folder are resolved:
|
||||
// https://github.com/facebookincubator/create-react-app/issues/637
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {literal, nativeEnum, number, string, strictObject, union} from 'zod';
|
||||
import type {infer as zodInfer} from 'zod';
|
||||
import {literal, nativeEnum, number, strictObject, string, union} from 'zod';
|
||||
|
||||
import {AccessLevel} from './constants/Auth';
|
||||
import {clientConnectionSettingsSchema} from './ClientConnectionSettings';
|
||||
import {AccessLevel} from './constants/Auth';
|
||||
|
||||
export const authMethodSchema = union([literal('default'), literal('none')]);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {literal, number, string, strictObject, union} from 'zod';
|
||||
import type {infer as zodInfer} from 'zod';
|
||||
import {literal, number, strictObject, string, union} from 'zod';
|
||||
|
||||
const delugeConnectionSettingsSchema = strictObject({
|
||||
client: literal('Deluge'),
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
// env variable FLOOD_OPTION_port=80 is equivalent to argument --port 80. Use ',' to split
|
||||
// for arguments that take multiple inputs such as --allowedpath.
|
||||
|
||||
import {array, boolean, number, strictObject, string} from 'zod';
|
||||
import type {infer as zodInfer} from 'zod';
|
||||
import {array, boolean, number, strictObject, string} from 'zod';
|
||||
|
||||
import {authMethodSchema} from './Auth';
|
||||
import {clientConnectionSettingsSchema} from './ClientConnectionSettings';
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import type {infer as zodInfer} from 'zod';
|
||||
|
||||
import {AccessLevel} from '../constants/Auth';
|
||||
import {credentialsSchema} from '../Auth';
|
||||
|
||||
import type {AuthMethod} from '../Auth';
|
||||
import {credentialsSchema} from '../Auth';
|
||||
import {AccessLevel} from '../constants/Auth';
|
||||
|
||||
// All auth requests are schema validated to ensure security.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {array, boolean, number, record, strictObject, string} from 'zod';
|
||||
import {noComma} from '../../util/regEx';
|
||||
|
||||
import type {infer as zodInfer} from 'zod';
|
||||
import {array, boolean, number, record, strictObject, string} from 'zod';
|
||||
|
||||
import {noComma} from '../../util/regEx';
|
||||
|
||||
const TAG_NO_COMMA_MESSAGE = {
|
||||
message: 'Tag must not contain comma',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type {TorrentStatus} from '../constants/torrentStatusMap';
|
||||
import type {TorrentContent} from './TorrentContent';
|
||||
import type {TorrentPeer} from './TorrentPeer';
|
||||
import type {TorrentStatus} from '../constants/torrentStatusMap';
|
||||
import type {TorrentTracker} from './TorrentTracker';
|
||||
|
||||
export interface TorrentDetails {
|
||||
|
||||
Reference in New Issue
Block a user