@ctrl/qbittorrent 2.10.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export * from './types.js';
2
+ export * from './qbittorrent.js';
@@ -0,0 +1,2 @@
1
+ export * from './types.js';
2
+ export * from './qbittorrent.js';
@@ -1,8 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { Options as GotOptions, Response } from 'got';
3
- import { AddTorrentOptions as NormalizedAddTorrentOptions, TorrentClient, TorrentSettings } from '@ctrl/shared-torrent';
4
- import { AddMagnetOptions, AddTorrentOptions, AllClientDataQbittorrent, BuildInfo, Categories, NormalizedTorrentQbittorrent, Preferences, Torrent, TorrentFile, TorrentFilePriority, TorrentFilters, TorrentPieceState, TorrentProperties, TorrentState, TorrentTrackers, TorrentTrackerStatus, WebSeed } from './types';
5
- export { TorrentState, TorrentTrackerStatus, TorrentFilePriority, TorrentPieceState };
3
+ import { AddTorrentOptions as NormalizedAddTorrentOptions, AllClientData, NormalizedTorrent, TorrentClient, TorrentSettings } from '@ctrl/shared-torrent';
4
+ import { AddMagnetOptions, AddTorrentOptions, BuildInfo, Preferences, Torrent, TorrentCategories, TorrentFile, TorrentFilePriority, TorrentFilters, TorrentPieceState, TorrentProperties, TorrentTrackers, WebSeed } from './types.js';
6
5
  export declare class QBittorrent implements TorrentClient {
7
6
  config: TorrentSettings;
8
7
  /**
@@ -28,7 +27,7 @@ export declare class QBittorrent implements TorrentClient {
28
27
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#get-build-info}
29
28
  */
30
29
  getBuildInfo(): Promise<BuildInfo>;
31
- getTorrent(hash: string): Promise<NormalizedTorrentQbittorrent>;
30
+ getTorrent(hash: string): Promise<NormalizedTorrent>;
32
31
  /**
33
32
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#get-application-preferences}
34
33
  */
@@ -44,8 +43,16 @@ export declare class QBittorrent implements TorrentClient {
44
43
  * @param category Get torrents with the given category (empty string means "without category"; no "category" parameter means "any category")
45
44
  * @returns list of torrents
46
45
  */
47
- listTorrents(hashes?: string | string[], filter?: TorrentFilters, category?: string, sort?: string, offset?: number, reverse?: boolean, tag?: string): Promise<Torrent[]>;
48
- getAllData(): Promise<AllClientDataQbittorrent>;
46
+ listTorrents({ hashes, filter, category, sort, offset, reverse, tag, }?: {
47
+ hashes?: string | string[];
48
+ filter?: TorrentFilters;
49
+ sort?: string;
50
+ tag?: string;
51
+ category?: string;
52
+ offset?: number;
53
+ reverse?: boolean;
54
+ }): Promise<Torrent[]>;
55
+ getAllData(): Promise<AllClientData>;
49
56
  /**
50
57
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#get-torrent-generic-properties}
51
58
  */
@@ -95,7 +102,7 @@ export declare class QBittorrent implements TorrentClient {
95
102
  /**
96
103
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#get-all-categories}
97
104
  */
98
- getCategories(): Promise<Categories>;
105
+ getCategories(): Promise<TorrentCategories>;
99
106
  /**
100
107
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#add-new-category}
101
108
  */
@@ -146,7 +153,7 @@ export declare class QBittorrent implements TorrentClient {
146
153
  */
147
154
  reannounceTorrent(hashes: string | string[] | 'all'): Promise<boolean>;
148
155
  addTorrent(torrent: string | Buffer, options?: Partial<AddTorrentOptions>): Promise<boolean>;
149
- normalizedAddTorrent(torrent: string | Buffer, options?: Partial<NormalizedAddTorrentOptions>): Promise<NormalizedTorrentQbittorrent>;
156
+ normalizedAddTorrent(torrent: string | Buffer, options?: Partial<NormalizedAddTorrentOptions>): Promise<NormalizedTorrent>;
150
157
  /**
151
158
  * @param hash Hash for desired torrent
152
159
  * @param id id of the file to be renamed
@@ -191,7 +198,7 @@ export declare class QBittorrent implements TorrentClient {
191
198
  */
192
199
  login(): Promise<boolean>;
193
200
  logout(): boolean;
194
- request<T extends object | string>(path: string, method: GotOptions['method'], params?: any, body?: GotOptions['body'], headers?: any, json?: boolean): Promise<Response<T>>;
201
+ request<T extends object | string>(path: string, method: GotOptions['method'], params?: any, body?: GotOptions['body'], form?: GotOptions['form'], headers?: any, json?: boolean): Promise<Response<T>>;
195
202
  /**
196
203
  * Normalizes hashes
197
204
  * @returns hashes as string seperated by `|`
@@ -1,23 +1,15 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.QBittorrent = exports.TorrentPieceState = exports.TorrentFilePriority = exports.TorrentTrackerStatus = exports.TorrentState = void 0;
7
1
  /* eslint-disable @typescript-eslint/ban-types */
8
- const fs_1 = require("fs");
9
- const url_1 = require("url");
10
- const form_data_1 = __importDefault(require("form-data"));
11
- const got_1 = __importDefault(require("got"));
12
- const tough_cookie_1 = require("tough-cookie");
13
- const shared_torrent_1 = require("@ctrl/shared-torrent");
14
- const torrent_file_1 = require("@ctrl/torrent-file");
15
- const url_join_1 = require("@ctrl/url-join");
16
- const types_1 = require("./types");
17
- Object.defineProperty(exports, "TorrentFilePriority", { enumerable: true, get: function () { return types_1.TorrentFilePriority; } });
18
- Object.defineProperty(exports, "TorrentPieceState", { enumerable: true, get: function () { return types_1.TorrentPieceState; } });
19
- Object.defineProperty(exports, "TorrentState", { enumerable: true, get: function () { return types_1.TorrentState; } });
20
- Object.defineProperty(exports, "TorrentTrackerStatus", { enumerable: true, get: function () { return types_1.TorrentTrackerStatus; } });
2
+ import { existsSync } from 'fs';
3
+ import { URLSearchParams } from 'url';
4
+ import { File, FormData } from 'formdata-node';
5
+ import { fileFromPath } from 'formdata-node/file-from-path';
6
+ import got from 'got';
7
+ import { Cookie } from 'tough-cookie';
8
+ import { magnetDecode } from '@ctrl/magnet-link';
9
+ import { TorrentState as NormalizedTorrentState, } from '@ctrl/shared-torrent';
10
+ import { hash } from '@ctrl/torrent-file';
11
+ import { urlJoin } from '@ctrl/url-join';
12
+ import { TorrentState, } from './types.js';
21
13
  const defaults = {
22
14
  baseUrl: 'http://localhost:9091/',
23
15
  path: '/api/v2',
@@ -25,8 +17,32 @@ const defaults = {
25
17
  password: '',
26
18
  timeout: 5000,
27
19
  };
28
- class QBittorrent {
20
+ export class QBittorrent {
29
21
  constructor(options = {}) {
22
+ Object.defineProperty(this, "config", {
23
+ enumerable: true,
24
+ configurable: true,
25
+ writable: true,
26
+ value: void 0
27
+ });
28
+ /**
29
+ * auth cookie
30
+ */
31
+ Object.defineProperty(this, "_sid", {
32
+ enumerable: true,
33
+ configurable: true,
34
+ writable: true,
35
+ value: void 0
36
+ });
37
+ /**
38
+ * cookie expiration
39
+ */
40
+ Object.defineProperty(this, "_exp", {
41
+ enumerable: true,
42
+ configurable: true,
43
+ writable: true,
44
+ value: void 0
45
+ });
30
46
  this.config = { ...defaults, ...options };
31
47
  }
32
48
  /**
@@ -40,11 +56,11 @@ class QBittorrent {
40
56
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#get-application-version}
41
57
  */
42
58
  async getAppVersion() {
43
- const res = await this.request('/app/version', 'GET', undefined, undefined, undefined, false);
59
+ const res = await this.request('/app/version', 'GET', undefined, undefined, undefined, undefined, false);
44
60
  return res.body;
45
61
  }
46
62
  async getApiVersion() {
47
- const res = await this.request('/app/webapiVersion', 'GET', undefined, undefined, undefined, false);
63
+ const res = await this.request('/app/webapiVersion', 'GET', undefined, undefined, undefined, undefined, false);
48
64
  return res.body;
49
65
  }
50
66
  /**
@@ -55,7 +71,7 @@ class QBittorrent {
55
71
  return res.body;
56
72
  }
57
73
  async getTorrent(hash) {
58
- const torrentsResponse = await this.listTorrents(hash);
74
+ const torrentsResponse = await this.listTorrents({ hashes: hash });
59
75
  const torrentData = torrentsResponse[0];
60
76
  if (!torrentData) {
61
77
  throw new Error('Torrent not found');
@@ -73,9 +89,9 @@ class QBittorrent {
73
89
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#set-application-preferences}
74
90
  */
75
91
  async setPreferences(preferences) {
76
- const form = new form_data_1.default();
77
- form.append('json', JSON.stringify(preferences));
78
- await this.request('/app/setPreferences', 'POST', undefined, form);
92
+ await this.request('/app/setPreferences', 'POST', undefined, undefined, {
93
+ json: JSON.stringify(preferences),
94
+ });
79
95
  return true;
80
96
  }
81
97
  /**
@@ -85,10 +101,7 @@ class QBittorrent {
85
101
  * @param category Get torrents with the given category (empty string means "without category"; no "category" parameter means "any category")
86
102
  * @returns list of torrents
87
103
  */
88
- // eslint-disable-next-line max-params
89
- async listTorrents(hashes, filter, category, sort, offset, reverse,
90
- // TODO: refactor filters into an object with optional properties
91
- tag) {
104
+ async listTorrents({ hashes, filter, category, sort, offset, reverse, tag, } = {}) {
92
105
  const params = {};
93
106
  if (hashes) {
94
107
  params.hashes = this._normalizeHashes(hashes);
@@ -193,20 +206,20 @@ class QBittorrent {
193
206
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#set-torrent-location}
194
207
  */
195
208
  async setTorrentLocation(hashes, location) {
196
- const form = new form_data_1.default();
197
- form.append('location', location);
198
- form.append('hashes', this._normalizeHashes(hashes));
199
- await this.request('/torrents/setLocation', 'POST', undefined, form);
209
+ await this.request('/torrents/setLocation', 'POST', undefined, undefined, {
210
+ location,
211
+ hashes: this._normalizeHashes(hashes),
212
+ });
200
213
  return true;
201
214
  }
202
215
  /**
203
216
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#set-torrent-name}
204
217
  */
205
218
  async setTorrentName(hash, name) {
206
- const form = new form_data_1.default();
207
- form.append('hash', hash);
208
- form.append('name', name);
209
- await this.request('/torrents/rename', 'POST', undefined, form);
219
+ await this.request('/torrents/rename', 'POST', undefined, undefined, {
220
+ hash,
221
+ name,
222
+ });
210
223
  return true;
211
224
  }
212
225
  /**
@@ -221,9 +234,9 @@ class QBittorrent {
221
234
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#create-tags}
222
235
  */
223
236
  async createTags(tags) {
224
- const form = new form_data_1.default();
225
- form.append('tags', tags);
226
- await this.request('/torrents/createTags', 'POST', undefined, form, undefined, false);
237
+ await this.request('/torrents/createTags', 'POST', undefined, undefined, {
238
+ tags,
239
+ }, undefined, false);
227
240
  return true;
228
241
  }
229
242
  /**
@@ -231,9 +244,7 @@ class QBittorrent {
231
244
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#delete-tags}
232
245
  */
233
246
  async deleteTags(tags) {
234
- const form = new form_data_1.default();
235
- form.append('tags', tags);
236
- await this.request('/torrents/deleteTags', 'POST', undefined, form, undefined, false);
247
+ await this.request('/torrents/deleteTags', 'POST', undefined, undefined, { tags }, undefined, false);
237
248
  return true;
238
249
  }
239
250
  /**
@@ -247,39 +258,39 @@ class QBittorrent {
247
258
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#add-new-category}
248
259
  */
249
260
  async createCategory(category, savePath = '') {
250
- const form = new form_data_1.default();
251
- form.append('category', category);
252
- form.append('savePath', savePath);
253
- await this.request('/torrents/createCategory', 'POST', undefined, form);
261
+ await this.request('/torrents/createCategory', 'POST', undefined, undefined, {
262
+ category,
263
+ savePath,
264
+ }, undefined, false);
254
265
  return true;
255
266
  }
256
267
  /**
257
268
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#edit-category}
258
269
  */
259
270
  async editCategory(category, savePath = '') {
260
- const form = new form_data_1.default();
261
- form.append('category', category);
262
- form.append('savePath', savePath);
263
- await this.request('/torrents/editCategory', 'POST', undefined, form, undefined, false);
271
+ await this.request('/torrents/editCategory', 'POST', undefined, undefined, {
272
+ category,
273
+ savePath,
274
+ }, undefined, false);
264
275
  return true;
265
276
  }
266
277
  /**
267
278
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#remove-categories}
268
279
  */
269
280
  async removeCategory(categories) {
270
- const form = new form_data_1.default();
271
- form.append('categories', categories);
272
- await this.request('/torrents/removeCategories', 'POST', undefined, form, undefined, false);
281
+ await this.request('/torrents/removeCategories', 'POST', undefined, undefined, {
282
+ categories,
283
+ }, undefined, false);
273
284
  return true;
274
285
  }
275
286
  /**
276
287
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#add-torrent-tags}
277
288
  */
278
289
  async addTorrentTags(hashes, tags) {
279
- const form = new form_data_1.default();
280
- form.append('hashes', this._normalizeHashes(hashes));
281
- form.append('tags', tags);
282
- await this.request('/torrents/addTags', 'POST', undefined, form, undefined, false);
290
+ await this.request('/torrents/addTags', 'POST', undefined, undefined, {
291
+ hashes: this._normalizeHashes(hashes),
292
+ tags,
293
+ }, undefined, false);
283
294
  return true;
284
295
  }
285
296
  /**
@@ -287,12 +298,11 @@ class QBittorrent {
287
298
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#remove-torrent-tags}
288
299
  */
289
300
  async removeTorrentTags(hashes, tags) {
290
- const form = new form_data_1.default();
291
- form.append('hashes', this._normalizeHashes(hashes));
301
+ const form = { hashes: this._normalizeHashes(hashes) };
292
302
  if (tags) {
293
- form.append('tags', tags);
303
+ form.tags = tags;
294
304
  }
295
- await this.request('/torrents/removeTags', 'POST', undefined, form, undefined, false);
305
+ await this.request('/torrents/removeTags', 'POST', undefined, undefined, form, undefined, false);
296
306
  return true;
297
307
  }
298
308
  /**
@@ -305,10 +315,10 @@ class QBittorrent {
305
315
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#set-torrent-category}
306
316
  */
307
317
  async setTorrentCategory(hashes, category = '') {
308
- const form = new form_data_1.default();
309
- form.append('hashes', this._normalizeHashes(hashes));
310
- form.append('category', category);
311
- await this.request('/torrents/setCategory', 'POST', undefined, form);
318
+ await this.request('/torrents/setCategory', 'POST', undefined, undefined, {
319
+ hashes: this._normalizeHashes(hashes),
320
+ category,
321
+ });
312
322
  return true;
313
323
  }
314
324
  /**
@@ -363,26 +373,25 @@ class QBittorrent {
363
373
  return true;
364
374
  }
365
375
  async addTorrent(torrent, options = {}) {
366
- var _a;
367
- const form = new form_data_1.default();
368
- const fileOptions = {
369
- contentType: 'application/x-bittorrent',
370
- filename: (_a = options.filename) !== null && _a !== void 0 ? _a : 'torrent',
371
- };
376
+ var _a, _b;
377
+ const form = new FormData();
372
378
  // remove options.filename, not used in form
373
379
  if (options.filename) {
374
380
  delete options.filename;
375
381
  }
382
+ const type = { type: 'application/x-bittorrent' };
376
383
  if (typeof torrent === 'string') {
377
- if ((0, fs_1.existsSync)(torrent)) {
378
- form.append('file', Buffer.from((0, fs_1.readFileSync)(torrent)), fileOptions);
384
+ if (existsSync(torrent)) {
385
+ const file = await fileFromPath(torrent, (_a = options.filename) !== null && _a !== void 0 ? _a : 'torrent', type);
386
+ form.set('file', file);
379
387
  }
380
388
  else {
381
- form.append('file', Buffer.from(torrent, 'base64'), fileOptions);
389
+ form.set('file', new File([Buffer.from(torrent, 'base64')], 'file.torrent', type));
382
390
  }
383
391
  }
384
392
  else {
385
- form.append('file', torrent, fileOptions);
393
+ const file = new File([torrent], (_b = options.filename) !== null && _b !== void 0 ? _b : 'torrent', type);
394
+ form.set('file', file);
386
395
  }
387
396
  if (options) {
388
397
  // disable savepath when autoTMM is defined
@@ -396,7 +405,7 @@ class QBittorrent {
396
405
  form.append(key, value);
397
406
  }
398
407
  }
399
- const res = await this.request('/torrents/add', 'POST', undefined, form, form.getHeaders(), false);
408
+ const res = await this.request('/torrents/add', 'POST', undefined, form, undefined, undefined, false);
400
409
  if (res.body === 'Fails.') {
401
410
  throw new Error('Failed to add torrent');
402
411
  }
@@ -410,11 +419,21 @@ class QBittorrent {
410
419
  if (options.label) {
411
420
  torrentOptions.category = options.label;
412
421
  }
413
- if (!Buffer.isBuffer(torrent)) {
414
- torrent = Buffer.from(torrent);
422
+ let torrentHash;
423
+ if (typeof torrent === 'string' && torrent.startsWith('magnet:')) {
424
+ torrentHash = magnetDecode(torrent).infoHash;
425
+ if (!torrentHash) {
426
+ throw new Error('Magnet did not contain hash');
427
+ }
428
+ await this.addMagnet(torrent, torrentOptions);
429
+ }
430
+ else {
431
+ if (!Buffer.isBuffer(torrent)) {
432
+ torrent = Buffer.from(torrent);
433
+ }
434
+ torrentHash = await hash(torrent);
435
+ await this.addTorrent(torrent, torrentOptions);
415
436
  }
416
- const torrentHash = await (0, torrent_file_1.hash)(torrent);
417
- await this.addTorrent(torrent, torrentOptions);
418
437
  return this.getTorrent(torrentHash);
419
438
  }
420
439
  /**
@@ -423,11 +442,11 @@ class QBittorrent {
423
442
  * @param name new name to be assigned to the file
424
443
  */
425
444
  async renameFile(hash, id, name) {
426
- const form = new form_data_1.default();
445
+ const form = new FormData();
427
446
  form.append('hash', hash);
428
447
  form.append('id', id);
429
448
  form.append('name', name);
430
- await this.request('/torrents/renameFile', 'POST', undefined, form, form.getHeaders(), false);
449
+ await this.request('/torrents/renameFile', 'POST', undefined, form, undefined, false);
431
450
  return true;
432
451
  }
433
452
  /**
@@ -435,7 +454,7 @@ class QBittorrent {
435
454
  * @param options
436
455
  */
437
456
  async addMagnet(urls, options = {}) {
438
- const form = new form_data_1.default();
457
+ const form = new FormData();
439
458
  form.append('urls', urls);
440
459
  if (options) {
441
460
  // disable savepath when autoTMM is defined
@@ -449,7 +468,7 @@ class QBittorrent {
449
468
  form.append(key, value);
450
469
  }
451
470
  }
452
- const res = await this.request('/torrents/add', 'POST', undefined, form, form.getHeaders(), false);
471
+ const res = await this.request('/torrents/add', 'POST', undefined, form, undefined, undefined, false);
453
472
  if (res.body === 'Fails.') {
454
473
  throw new Error('Failed to add torrent');
455
474
  }
@@ -523,23 +542,25 @@ class QBittorrent {
523
542
  * {@link https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#login}
524
543
  */
525
544
  async login() {
526
- const url = (0, url_join_1.urlJoin)(this.config.baseUrl, this.config.path, '/auth/login');
527
- const form = new form_data_1.default();
528
- form.append('username', this.config.username);
529
- form.append('password', this.config.password);
530
- const res = await got_1.default.post(url, {
531
- isStream: false,
532
- body: form,
545
+ var _a, _b;
546
+ const url = urlJoin(this.config.baseUrl, this.config.path, '/auth/login');
547
+ const res = await got({
548
+ url,
549
+ method: 'POST',
550
+ form: {
551
+ username: (_a = this.config.username) !== null && _a !== void 0 ? _a : '',
552
+ password: (_b = this.config.password) !== null && _b !== void 0 ? _b : '',
553
+ },
533
554
  followRedirect: false,
534
- retry: 0,
555
+ retry: { limit: 0 },
556
+ timeout: { request: this.config.timeout },
535
557
  // allow proxy agent
536
- agent: this.config.agent,
537
- timeout: this.config.timeout,
558
+ ...(this.config.agent ? { agent: this.config.agent } : {}),
538
559
  });
539
560
  if (!res.headers['set-cookie'] || !res.headers['set-cookie'].length) {
540
561
  throw new Error('Cookie not found. Auth Failed.');
541
562
  }
542
- const cookie = tough_cookie_1.Cookie.parse(res.headers['set-cookie'][0]);
563
+ const cookie = Cookie.parse(res.headers['set-cookie'][0]);
543
564
  if (!cookie || cookie.key !== 'SID') {
544
565
  throw new Error('Invalid cookie');
545
566
  }
@@ -553,7 +574,7 @@ class QBittorrent {
553
574
  return true;
554
575
  }
555
576
  // eslint-disable-next-line max-params
556
- async request(path, method, params = {}, body, headers = {}, json = true) {
577
+ async request(path, method, params = {}, body, form, headers = {}, json = true) {
557
578
  var _a;
558
579
  if (!this._sid || !this._exp || this._exp.getTime() < new Date().getTime()) {
559
580
  const authed = await this.login();
@@ -561,8 +582,8 @@ class QBittorrent {
561
582
  throw new Error('Auth Failed');
562
583
  }
563
584
  }
564
- const url = (0, url_join_1.urlJoin)(this.config.baseUrl, this.config.path, path);
565
- const res = await (0, got_1.default)(url, {
585
+ const url = urlJoin(this.config.baseUrl, this.config.path, path);
586
+ const res = await got(url, {
566
587
  isStream: false,
567
588
  resolveBodyOnly: false,
568
589
  method,
@@ -570,13 +591,14 @@ class QBittorrent {
570
591
  Cookie: `SID=${(_a = this._sid) !== null && _a !== void 0 ? _a : ''}`,
571
592
  ...headers,
572
593
  },
573
- retry: 0,
594
+ retry: { limit: 0 },
574
595
  body,
575
- searchParams: new url_1.URLSearchParams(params),
596
+ form,
597
+ searchParams: new URLSearchParams(params),
576
598
  // allow proxy agent
577
- agent: this.config.agent,
578
- timeout: this.config.timeout,
599
+ timeout: { request: this.config.timeout },
579
600
  responseType: json ? 'json' : 'text',
601
+ ...(this.config.agent ? { agent: this.config.agent } : {}),
580
602
  });
581
603
  return res;
582
604
  }
@@ -591,40 +613,40 @@ class QBittorrent {
591
613
  return hashes;
592
614
  }
593
615
  _normalizeTorrentData(torrent) {
594
- let state = shared_torrent_1.TorrentState.unknown;
616
+ let state = NormalizedTorrentState.unknown;
595
617
  switch (torrent.state) {
596
- case types_1.TorrentState.ForcedDL:
597
- case types_1.TorrentState.MetaDL:
598
- state = shared_torrent_1.TorrentState.downloading;
618
+ case TorrentState.ForcedDL:
619
+ case TorrentState.MetaDL:
620
+ state = NormalizedTorrentState.downloading;
599
621
  break;
600
- case types_1.TorrentState.Allocating:
622
+ case TorrentState.Allocating:
601
623
  // state = 'stalledDL';
602
- state = shared_torrent_1.TorrentState.queued;
624
+ state = NormalizedTorrentState.queued;
603
625
  break;
604
- case types_1.TorrentState.ForcedUP:
605
- state = shared_torrent_1.TorrentState.seeding;
626
+ case TorrentState.ForcedUP:
627
+ state = NormalizedTorrentState.seeding;
606
628
  break;
607
- case types_1.TorrentState.PausedDL:
608
- state = shared_torrent_1.TorrentState.paused;
629
+ case TorrentState.PausedDL:
630
+ state = NormalizedTorrentState.paused;
609
631
  break;
610
- case types_1.TorrentState.PausedUP:
632
+ case TorrentState.PausedUP:
611
633
  // state = 'completed';
612
- state = shared_torrent_1.TorrentState.paused;
634
+ state = NormalizedTorrentState.paused;
613
635
  break;
614
- case types_1.TorrentState.QueuedDL:
615
- case types_1.TorrentState.QueuedUP:
616
- state = shared_torrent_1.TorrentState.queued;
636
+ case TorrentState.QueuedDL:
637
+ case TorrentState.QueuedUP:
638
+ state = NormalizedTorrentState.queued;
617
639
  break;
618
- case types_1.TorrentState.CheckingDL:
619
- case types_1.TorrentState.CheckingUP:
620
- case types_1.TorrentState.QueuedForChecking:
621
- case types_1.TorrentState.CheckingResumeData:
622
- case types_1.TorrentState.Moving:
623
- state = shared_torrent_1.TorrentState.checking;
640
+ case TorrentState.CheckingDL:
641
+ case TorrentState.CheckingUP:
642
+ case TorrentState.QueuedForChecking:
643
+ case TorrentState.CheckingResumeData:
644
+ case TorrentState.Moving:
645
+ state = NormalizedTorrentState.checking;
624
646
  break;
625
- case types_1.TorrentState.Unknown:
626
- case types_1.TorrentState.MissingFiles:
627
- state = shared_torrent_1.TorrentState.error;
647
+ case TorrentState.Unknown:
648
+ case TorrentState.MissingFiles:
649
+ state = NormalizedTorrentState.error;
628
650
  break;
629
651
  default:
630
652
  break;
@@ -658,4 +680,3 @@ class QBittorrent {
658
680
  return result;
659
681
  }
660
682
  }
661
- exports.QBittorrent = QBittorrent;
@@ -1,13 +1,3 @@
1
- import { AllClientData, NormalizedTorrent } from '@ctrl/shared-torrent';
2
- /**
3
- * refine the normalized torrent options for qbittorrent
4
- */
5
- export interface NormalizedTorrentQbittorrent extends NormalizedTorrent {
6
- id: string;
7
- }
8
- export interface AllClientDataQbittorrent extends AllClientData {
9
- torrents: NormalizedTorrentQbittorrent[];
10
- }
11
1
  export interface BuildInfo {
12
2
  /**
13
3
  * QT version
@@ -176,8 +166,8 @@ export interface Torrent {
176
166
  */
177
167
  category: string;
178
168
  }
179
- export declare type Categories = Record<string, Category>;
180
- export interface Category {
169
+ export declare type TorrentCategories = Record<string, Category>;
170
+ interface Category {
181
171
  name: string;
182
172
  savePath: string;
183
173
  }
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TorrentPieceState = exports.TorrentFilePriority = exports.TorrentTrackerStatus = exports.TorrentState = void 0;
4
- var TorrentState;
1
+ export var TorrentState;
5
2
  (function (TorrentState) {
6
3
  /**
7
4
  * Some error occurred, applies to paused torrents
@@ -80,8 +77,8 @@ var TorrentState;
80
77
  * Torrent data files is missing
81
78
  */
82
79
  TorrentState["MissingFiles"] = "missingFiles";
83
- })(TorrentState = exports.TorrentState || (exports.TorrentState = {}));
84
- var TorrentTrackerStatus;
80
+ })(TorrentState || (TorrentState = {}));
81
+ export var TorrentTrackerStatus;
85
82
  (function (TorrentTrackerStatus) {
86
83
  /**
87
84
  * Tracker is disabled (used for DHT, PeX, and LSD)
@@ -103,8 +100,8 @@ var TorrentTrackerStatus;
103
100
  * Tracker has not been contacted yet
104
101
  */
105
102
  TorrentTrackerStatus[TorrentTrackerStatus["Waiting"] = 4] = "Waiting";
106
- })(TorrentTrackerStatus = exports.TorrentTrackerStatus || (exports.TorrentTrackerStatus = {}));
107
- var TorrentFilePriority;
103
+ })(TorrentTrackerStatus || (TorrentTrackerStatus = {}));
104
+ export var TorrentFilePriority;
108
105
  (function (TorrentFilePriority) {
109
106
  /**
110
107
  * Do not download
@@ -122,8 +119,8 @@ var TorrentFilePriority;
122
119
  * Maximal priority
123
120
  */
124
121
  TorrentFilePriority[TorrentFilePriority["MaxPriority"] = 7] = "MaxPriority";
125
- })(TorrentFilePriority = exports.TorrentFilePriority || (exports.TorrentFilePriority = {}));
126
- var TorrentPieceState;
122
+ })(TorrentFilePriority || (TorrentFilePriority = {}));
123
+ export var TorrentPieceState;
127
124
  (function (TorrentPieceState) {
128
125
  /**
129
126
  * Not downloaded yet
@@ -137,4 +134,4 @@ var TorrentPieceState;
137
134
  * Already downloaded
138
135
  */
139
136
  TorrentPieceState[TorrentPieceState["Downloaded"] = 2] = "Downloaded";
140
- })(TorrentPieceState = exports.TorrentPieceState || (exports.TorrentPieceState = {}));
137
+ })(TorrentPieceState || (TorrentPieceState = {}));
package/package.json CHANGED
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "name": "@ctrl/qbittorrent",
3
- "version": "2.10.0",
3
+ "version": "3.0.0",
4
4
  "description": "TypeScript api wrapper for qbittorrent using got",
5
5
  "author": "Scott Cooper <scttcper@gmail.com>",
6
6
  "license": "MIT",
7
7
  "repository": "scttcper/qbittorrent",
8
- "main": "dist/index.js",
9
- "types": "dist/index.d.ts",
8
+ "homepage": "https://qbittorrent.vercel.app",
9
+ "type": "module",
10
+ "main": "./dist/src/index.js",
11
+ "typings": "./dist/src/index.d.ts",
10
12
  "files": [
11
- "dist"
13
+ "dist/src"
12
14
  ],
13
15
  "sideEffects": false,
14
16
  "publishConfig": {
@@ -22,49 +24,48 @@
22
24
  "lint": "eslint --ext .js,.ts, .",
23
25
  "lint:fix": "eslint --fix --ext .js,.ts, .",
24
26
  "prepare": "npm run build",
25
- "build": "tsc -p tsconfig.build.json",
27
+ "build": "tsc",
26
28
  "build:docs": "typedoc",
27
- "test": "jest --runInBand",
28
- "test:watch": "jest --watch --runInBand",
29
- "test:ci": "jest --ci --reporters=default --reporters=jest-junit --runInBand --coverage"
29
+ "test": "ava",
30
+ "test:watch": "ava --watch",
31
+ "test:ci": "c8 --reporter=text --reporter=lcov ava"
30
32
  },
31
33
  "dependencies": {
32
- "@ctrl/shared-torrent": "^3.0.5",
33
- "@ctrl/torrent-file": "^1.3.3",
34
- "@ctrl/url-join": "^1.0.4",
35
- "form-data": "^4.0.0",
36
- "got": "^11.8.2",
34
+ "@ctrl/magnet-link": "^3.1.0",
35
+ "@ctrl/shared-torrent": "^4.1.0",
36
+ "@ctrl/torrent-file": "^2.0.1",
37
+ "@ctrl/url-join": "^2.0.0",
38
+ "formdata-node": "^4.3.2",
39
+ "got": "^12.0.1",
37
40
  "tough-cookie": "^4.0.0"
38
41
  },
39
42
  "devDependencies": {
40
- "@babel/plugin-transform-modules-commonjs": "7.16.0",
41
- "@babel/preset-typescript": "7.16.0",
42
- "@ctrl/eslint-config": "3.1.1",
43
- "@jest/globals": "27.3.1",
44
- "@types/form-data": "2.5.0",
45
- "@types/node": "16.11.6",
43
+ "@ctrl/eslint-config": "3.3.1",
44
+ "@sindresorhus/tsconfig": "2.0.0",
45
+ "@types/node": "17.0.21",
46
46
  "@types/tough-cookie": "4.0.1",
47
- "jest-junit": "13.0.0",
48
- "jest": "27.3.1",
49
- "p-wait-for": "3.2.0",
50
- "typedoc": "0.22.8",
51
- "typescript": "4.4.4"
47
+ "ava": "4.0.1",
48
+ "c8": "7.11.0",
49
+ "p-wait-for": "4.1.0",
50
+ "ts-node": "10.5.0",
51
+ "typedoc": "0.22.12",
52
+ "typescript": "4.5.5"
52
53
  },
53
- "jest": {
54
- "testEnvironment": "node"
55
- },
56
- "babel": {
57
- "presets": [
58
- "@babel/preset-typescript"
54
+ "ava": {
55
+ "files": [
56
+ "test/**/*.spec.ts"
59
57
  ],
60
- "plugins": [
61
- "@babel/plugin-transform-modules-commonjs"
58
+ "extensions": {
59
+ "ts": "module"
60
+ },
61
+ "nodeArguments": [
62
+ "--loader=ts-node/esm"
62
63
  ]
63
64
  },
64
65
  "release": {
65
66
  "branch": "master"
66
67
  },
67
68
  "engines": {
68
- "node": ">=10.19.0"
69
+ "node": ">=14.16"
69
70
  }
70
71
  }