@ctrl/deluge 4.3.1 → 5.0.1
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.
- package/README.md +18 -2
- package/dist/src/deluge.d.ts +2 -3
- package/dist/src/deluge.js +83 -132
- package/dist/src/normalizeTorrentData.d.ts +3 -0
- package/dist/src/normalizeTorrentData.js +37 -0
- package/package.json +19 -19
package/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
# deluge [](https://www.npmjs.com/package/@ctrl/deluge) [](https://www.npmjs.com/package/@ctrl/deluge) [](https://codecov.io/gh/scttcper/deluge)
|
2
2
|
|
3
|
-
> TypeScript api wrapper for [deluge](https://deluge-torrent.org/) using [
|
3
|
+
> TypeScript api wrapper for [deluge](https://deluge-torrent.org/) using [ofetch](https://github.com/unjs/ofetch)
|
4
4
|
|
5
5
|
### Install
|
6
6
|
|
@@ -75,3 +75,19 @@ transmission - https://github.com/scttcper/transmission
|
|
75
75
|
qbittorrent - https://github.com/scttcper/qbittorrent
|
76
76
|
utorrent - https://github.com/scttcper/utorrent
|
77
77
|
rtorrent - https://github.com/scttcper/rtorrent
|
78
|
+
|
79
|
+
### Start a test docker container
|
80
|
+
|
81
|
+
```
|
82
|
+
docker run -d \
|
83
|
+
--name=deluge \
|
84
|
+
-e PUID=1000 \
|
85
|
+
-e PGID=1000 \
|
86
|
+
-e TZ=Etc/UTC \
|
87
|
+
-e DELUGE_LOGLEVEL=error `#optional` \
|
88
|
+
-p 8112:8112 \
|
89
|
+
-p 6881:6881 \
|
90
|
+
-p 6881:6881/udp \
|
91
|
+
--restart unless-stopped \
|
92
|
+
lscr.io/linuxserver/deluge:latest
|
93
|
+
```
|
package/dist/src/deluge.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
2
|
-
import
|
2
|
+
import { FetchResponse } from 'ofetch';
|
3
3
|
import type { AddTorrentOptions as NormalizedAddTorrentOptions, AllClientData, NormalizedTorrent, TorrentClient, TorrentSettings } from '@ctrl/shared-torrent';
|
4
4
|
import type { AddTorrentOptions, AddTorrentResponse, BooleanStatus, ConfigResponse, DefaultResponse, DelugeSettings, GetHostsResponse, GetHostStatusResponse, ListMethods, PluginInfo, PluginsListResponse, StringStatus, TorrentFiles, TorrentInfo, TorrentListResponse, TorrentOptions, TorrentStatus, Tracker, UploadResponse } from './types.js';
|
5
5
|
export declare class Deluge implements TorrentClient {
|
@@ -106,7 +106,6 @@ export declare class Deluge implements TorrentClient {
|
|
106
106
|
getPluginInfo(plugins: string[]): Promise<PluginInfo>;
|
107
107
|
enablePlugin(plugins: string[]): Promise<DefaultResponse>;
|
108
108
|
disablePlugin(plugins: string[]): Promise<DefaultResponse>;
|
109
|
-
request<T extends object>(method: string, params?: any[], needsAuth?: boolean, autoConnect?: boolean): Promise<
|
110
|
-
private _normalizeTorrentData;
|
109
|
+
request<T extends object>(method: string, params?: any[], needsAuth?: boolean, autoConnect?: boolean): Promise<FetchResponse<T>>;
|
111
110
|
private _validateAuth;
|
112
111
|
}
|
package/dist/src/deluge.js
CHANGED
@@ -1,11 +1,9 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import { fileFromPath } from 'formdata-node/file-from-path';
|
4
|
-
import got from 'got';
|
1
|
+
import { FormData } from 'node-fetch-native';
|
2
|
+
import { ofetch } from 'ofetch';
|
5
3
|
import { Cookie } from 'tough-cookie';
|
4
|
+
import { joinURL } from 'ufo';
|
6
5
|
import { magnetDecode } from '@ctrl/magnet-link';
|
7
|
-
import {
|
8
|
-
import { urlJoin } from '@ctrl/url-join';
|
6
|
+
import { normalizeTorrentData } from './normalizeTorrentData.js';
|
9
7
|
const defaults = {
|
10
8
|
baseUrl: 'http://localhost:8112/',
|
11
9
|
path: '/json',
|
@@ -13,25 +11,10 @@ const defaults = {
|
|
13
11
|
timeout: 5000,
|
14
12
|
};
|
15
13
|
export class Deluge {
|
14
|
+
config;
|
15
|
+
_msgId = 0;
|
16
|
+
_cookie;
|
16
17
|
constructor(options = {}) {
|
17
|
-
Object.defineProperty(this, "config", {
|
18
|
-
enumerable: true,
|
19
|
-
configurable: true,
|
20
|
-
writable: true,
|
21
|
-
value: void 0
|
22
|
-
});
|
23
|
-
Object.defineProperty(this, "_msgId", {
|
24
|
-
enumerable: true,
|
25
|
-
configurable: true,
|
26
|
-
writable: true,
|
27
|
-
value: 0
|
28
|
-
});
|
29
|
-
Object.defineProperty(this, "_cookie", {
|
30
|
-
enumerable: true,
|
31
|
-
configurable: true,
|
32
|
-
writable: true,
|
33
|
-
value: void 0
|
34
|
-
});
|
35
18
|
this.config = { ...defaults, ...options };
|
36
19
|
}
|
37
20
|
resetSession() {
|
@@ -40,7 +23,7 @@ export class Deluge {
|
|
40
23
|
}
|
41
24
|
async getHosts() {
|
42
25
|
const res = await this.request('web.get_hosts', [], true, false);
|
43
|
-
return res.
|
26
|
+
return res._data;
|
44
27
|
}
|
45
28
|
/**
|
46
29
|
* Gets host status
|
@@ -48,7 +31,7 @@ export class Deluge {
|
|
48
31
|
*/
|
49
32
|
async getHostStatus(host) {
|
50
33
|
const res = await this.request('web.get_host_status', [host], true, false);
|
51
|
-
return res.
|
34
|
+
return res._data;
|
52
35
|
}
|
53
36
|
/**
|
54
37
|
* Connects deluge and returns a list of available methods
|
@@ -65,11 +48,11 @@ export class Deluge {
|
|
65
48
|
throw new Error('No hosts found');
|
66
49
|
}
|
67
50
|
const res = await this.request('web.connect', [host], true, false);
|
68
|
-
return res.
|
51
|
+
return res._data;
|
69
52
|
}
|
70
53
|
async connected() {
|
71
54
|
const res = await this.request('web.connected', [], true, false);
|
72
|
-
return res.
|
55
|
+
return res._data.result;
|
73
56
|
}
|
74
57
|
/**
|
75
58
|
* Disconnects deluge - warning all instances connected to this client will also be disconnected.
|
@@ -77,12 +60,13 @@ export class Deluge {
|
|
77
60
|
*/
|
78
61
|
async disconnect() {
|
79
62
|
const res = await this.request('web.disconnect', [], true, false);
|
63
|
+
const body = res._data;
|
80
64
|
// deluge 1.x returns a boolean and 2.x returns a string
|
81
|
-
if (typeof
|
82
|
-
return
|
65
|
+
if (typeof body.result === 'boolean') {
|
66
|
+
return body.result;
|
83
67
|
}
|
84
68
|
// "Connection was closed cleanly."
|
85
|
-
return
|
69
|
+
return body.result.includes('closed cleanly');
|
86
70
|
}
|
87
71
|
/**
|
88
72
|
* Checks current session is valid
|
@@ -101,7 +85,8 @@ export class Deluge {
|
|
101
85
|
if (this._cookie) {
|
102
86
|
try {
|
103
87
|
const check = await this.request('auth.check_session', undefined, false);
|
104
|
-
|
88
|
+
const body = await check.json();
|
89
|
+
if (body?.result) {
|
105
90
|
return true;
|
106
91
|
}
|
107
92
|
}
|
@@ -119,10 +104,10 @@ export class Deluge {
|
|
119
104
|
async login() {
|
120
105
|
this.resetSession();
|
121
106
|
const res = await this.request('auth.login', [this.config.password], false);
|
122
|
-
if (!res.
|
107
|
+
if (!res.ok || !res.headers?.get('set-cookie')?.length) {
|
123
108
|
throw new Error('Auth failed, incorrect password');
|
124
109
|
}
|
125
|
-
this._cookie = Cookie.parse(res.headers
|
110
|
+
this._cookie = Cookie.parse(res.headers.get('set-cookie'));
|
126
111
|
return true;
|
127
112
|
}
|
128
113
|
/**
|
@@ -131,15 +116,16 @@ export class Deluge {
|
|
131
116
|
*/
|
132
117
|
async logout() {
|
133
118
|
const res = await this.request('auth.delete_session');
|
119
|
+
const body = res._data;
|
134
120
|
this.resetSession();
|
135
|
-
return
|
121
|
+
return body.result;
|
136
122
|
}
|
137
123
|
/**
|
138
124
|
* returns the version ex - `2.0.3-2-201906121747-ubuntu18.04.1`
|
139
125
|
*/
|
140
126
|
async getVersion() {
|
141
127
|
const req = await this.request('daemon.get_version');
|
142
|
-
return req.
|
128
|
+
return req._data;
|
143
129
|
}
|
144
130
|
/**
|
145
131
|
* used to get torrent info before adding
|
@@ -147,7 +133,7 @@ export class Deluge {
|
|
147
133
|
*/
|
148
134
|
async getTorrentInfo(tmpPath) {
|
149
135
|
const res = await this.request('web.get_torrent_info', [tmpPath]);
|
150
|
-
return res.
|
136
|
+
return res._data;
|
151
137
|
}
|
152
138
|
/**
|
153
139
|
* Lists methods
|
@@ -156,7 +142,7 @@ export class Deluge {
|
|
156
142
|
*/
|
157
143
|
async listMethods(auth = true) {
|
158
144
|
const req = await this.request('system.listMethods', undefined, auth);
|
159
|
-
return req.
|
145
|
+
return req._data;
|
160
146
|
}
|
161
147
|
async upload(torrent) {
|
162
148
|
await this._validateAuth();
|
@@ -167,28 +153,23 @@ export class Deluge {
|
|
167
153
|
const form = new FormData();
|
168
154
|
const type = { type: 'application/x-bittorrent' };
|
169
155
|
if (typeof torrent === 'string') {
|
170
|
-
|
171
|
-
const file = await fileFromPath(torrent, 'temp.torrent', type);
|
172
|
-
form.set('file', file);
|
173
|
-
}
|
174
|
-
else {
|
175
|
-
form.set('file', new File([Buffer.from(torrent, 'base64')], 'file.torrent', type));
|
176
|
-
}
|
156
|
+
form.set('file', new File([Buffer.from(torrent, 'base64')], 'file.torrent', type));
|
177
157
|
}
|
178
158
|
else {
|
179
159
|
const file = new File([torrent], 'torrent', type);
|
180
160
|
form.set('file', file);
|
181
161
|
}
|
182
|
-
const url =
|
183
|
-
const res = await
|
162
|
+
const url = joinURL(this.config.baseUrl, '/upload');
|
163
|
+
const res = await ofetch(url, {
|
164
|
+
method: 'POST',
|
184
165
|
body: form,
|
185
|
-
retry:
|
186
|
-
timeout:
|
187
|
-
|
188
|
-
|
166
|
+
retry: 0,
|
167
|
+
timeout: this.config.timeout,
|
168
|
+
parseResponse: JSON.parse,
|
169
|
+
// @ts-expect-error for some reason agent is not in the type
|
170
|
+
agent: this.config.agent,
|
189
171
|
});
|
190
|
-
|
191
|
-
return JSON.parse(res.body);
|
172
|
+
return res;
|
192
173
|
}
|
193
174
|
/**
|
194
175
|
* Download a torrent from url, pass the result to {@link Deluge.addTorrent}
|
@@ -198,10 +179,11 @@ export class Deluge {
|
|
198
179
|
*/
|
199
180
|
async downloadFromUrl(url, cookies = '') {
|
200
181
|
const res = await this.request('web.download_torrent_from_url', [url, cookies]);
|
201
|
-
|
182
|
+
const body = res._data;
|
183
|
+
if (!body.result) {
|
202
184
|
throw new Error('Failed to download torrent');
|
203
185
|
}
|
204
|
-
return
|
186
|
+
return body.result;
|
205
187
|
}
|
206
188
|
async addTorrent(torrent, config = {}) {
|
207
189
|
let path;
|
@@ -236,10 +218,11 @@ export class Deluge {
|
|
236
218
|
...config,
|
237
219
|
};
|
238
220
|
const res = await this.request('web.add_torrents', [[{ path, options }]]);
|
239
|
-
|
221
|
+
const body = res._data;
|
222
|
+
if (!body.result) {
|
240
223
|
throw new Error('Failed to add torrent');
|
241
224
|
}
|
242
|
-
return
|
225
|
+
return body;
|
243
226
|
}
|
244
227
|
async normalizedAddTorrent(torrent, options = {}) {
|
245
228
|
const torrentOptions = {};
|
@@ -289,7 +272,7 @@ export class Deluge {
|
|
289
272
|
...config,
|
290
273
|
};
|
291
274
|
const res = await this.request('core.add_torrent_magnet', [magnet, options]);
|
292
|
-
return res.
|
275
|
+
return res._data;
|
293
276
|
}
|
294
277
|
/**
|
295
278
|
*
|
@@ -298,20 +281,21 @@ export class Deluge {
|
|
298
281
|
*/
|
299
282
|
async removeTorrent(torrentId, removeData = true) {
|
300
283
|
const req = await this.request('core.remove_torrent', [torrentId, removeData]);
|
301
|
-
return req.
|
284
|
+
return req._data;
|
302
285
|
}
|
303
286
|
async changePassword(password) {
|
304
287
|
const res = await this.request('auth.change_password', [
|
305
288
|
this.config.password,
|
306
289
|
password,
|
307
290
|
]);
|
308
|
-
|
291
|
+
const body = res._data;
|
292
|
+
if (!body.result || !res.headers.get('set-cookie')?.length) {
|
309
293
|
throw new Error('Old password incorrect');
|
310
294
|
}
|
311
295
|
// update current password to new password
|
312
296
|
this.config.password = password;
|
313
|
-
this._cookie = Cookie.parse(res.headers
|
314
|
-
return
|
297
|
+
this._cookie = Cookie.parse(res.headers.get('set-cookie'));
|
298
|
+
return body;
|
315
299
|
}
|
316
300
|
async getAllData() {
|
317
301
|
const listTorrents = await this.listTorrents();
|
@@ -322,7 +306,7 @@ export class Deluge {
|
|
322
306
|
};
|
323
307
|
for (const id of Object.keys(listTorrents.result.torrents)) {
|
324
308
|
const torrent = listTorrents.result.torrents[id];
|
325
|
-
const torrentData =
|
309
|
+
const torrentData = normalizeTorrentData(id, torrent);
|
326
310
|
results.torrents.push(torrentData);
|
327
311
|
}
|
328
312
|
if (listTorrents.result.filters.label) {
|
@@ -369,11 +353,11 @@ export class Deluge {
|
|
369
353
|
[...new Set(fields)],
|
370
354
|
filter,
|
371
355
|
]);
|
372
|
-
return req.
|
356
|
+
return req._data;
|
373
357
|
}
|
374
358
|
async getTorrent(id) {
|
375
359
|
const torrentResponse = await this.getTorrentStatus(id);
|
376
|
-
return
|
360
|
+
return normalizeTorrentData(id, torrentResponse.result);
|
377
361
|
}
|
378
362
|
/**
|
379
363
|
* get torrent state/status
|
@@ -424,103 +408,104 @@ export class Deluge {
|
|
424
408
|
...additionalFields,
|
425
409
|
];
|
426
410
|
const req = await this.request('web.get_torrent_status', [torrentId, fields]);
|
427
|
-
|
411
|
+
const body = req._data;
|
412
|
+
if (!body.result || !Object.keys(body.result).length) {
|
428
413
|
throw new Error('Torrent not found');
|
429
414
|
}
|
430
|
-
return
|
415
|
+
return body;
|
431
416
|
}
|
432
417
|
/**
|
433
418
|
* Get list of files for a torrent
|
434
419
|
*/
|
435
420
|
async getTorrentFiles(torrentId) {
|
436
421
|
const req = await this.request('web.get_torrent_files', [torrentId]);
|
437
|
-
return req.
|
422
|
+
return req._data;
|
438
423
|
}
|
439
424
|
async pauseTorrent(torrentId) {
|
440
425
|
const req = await this.request('core.pause_torrent', [[torrentId]]);
|
441
|
-
return req.
|
426
|
+
return req._data;
|
442
427
|
}
|
443
428
|
async resumeTorrent(torrentId) {
|
444
429
|
const req = await this.request('core.resume_torrent', [[torrentId]]);
|
445
|
-
return req.
|
430
|
+
return req._data;
|
446
431
|
}
|
447
432
|
async setTorrentOptions(torrentId, options = {}) {
|
448
433
|
const req = await this.request('core.set_torrent_options', [
|
449
434
|
[torrentId],
|
450
435
|
options,
|
451
436
|
]);
|
452
|
-
return req.
|
437
|
+
return req._data;
|
453
438
|
}
|
454
439
|
async setTorrentTrackers(torrentId, trackers = []) {
|
455
440
|
const req = await this.request('core.set_torrent_trackers', [
|
456
441
|
[torrentId],
|
457
442
|
trackers,
|
458
443
|
]);
|
459
|
-
return req.
|
444
|
+
return req._data;
|
460
445
|
}
|
461
446
|
async updateTorrentTrackers(torrentId) {
|
462
447
|
const req = await this.request('core.force_reannounce', [[torrentId]]);
|
463
|
-
return req.
|
448
|
+
return req._data;
|
464
449
|
}
|
465
450
|
async verifyTorrent(torrentId) {
|
466
451
|
const req = await this.request('core.force_recheck', [[torrentId]]);
|
467
|
-
return req.
|
452
|
+
return req._data;
|
468
453
|
}
|
469
454
|
async setTorrentLabel(torrentId, label) {
|
470
455
|
const req = await this.request('label.set_torrent', [torrentId, label]);
|
471
|
-
return req.
|
456
|
+
return req._data;
|
472
457
|
}
|
473
458
|
async addLabel(label) {
|
474
459
|
const req = await this.request('label.add', [label]);
|
475
|
-
return req.
|
460
|
+
return req._data;
|
476
461
|
}
|
477
462
|
async removeLabel(label) {
|
478
463
|
const req = await this.request('label.remove', [label]);
|
479
|
-
return req.
|
464
|
+
return req._data;
|
480
465
|
}
|
481
466
|
async getLabels() {
|
482
467
|
const req = await this.request('label.get_labels', []);
|
483
|
-
return req.
|
468
|
+
return req._data;
|
484
469
|
}
|
485
470
|
async queueTop(torrentId) {
|
486
471
|
const req = await this.request('core.queue_top', [[torrentId]]);
|
487
|
-
return req.
|
472
|
+
return req._data;
|
488
473
|
}
|
489
474
|
async queueBottom(torrentId) {
|
490
475
|
const req = await this.request('core.queue_bottom', [[torrentId]]);
|
491
|
-
return req.
|
476
|
+
return req._data;
|
492
477
|
}
|
493
478
|
async queueUp(torrentId) {
|
494
479
|
const req = await this.request('core.queue_up', [[torrentId]]);
|
495
|
-
return req.
|
480
|
+
return req._data;
|
496
481
|
}
|
497
482
|
async queueDown(torrentId) {
|
498
483
|
const req = await this.request('core.queue_down', [[torrentId]]);
|
499
|
-
return req.
|
484
|
+
return req._data;
|
500
485
|
}
|
501
486
|
async getConfig() {
|
502
487
|
const req = await this.request('core.get_config', []);
|
503
|
-
return req.
|
488
|
+
return req._data;
|
504
489
|
}
|
505
490
|
async setConfig(config) {
|
506
491
|
const req = await this.request('core.set_config', [config]);
|
507
|
-
return req.
|
492
|
+
return req._data;
|
508
493
|
}
|
509
494
|
async getPlugins() {
|
510
495
|
const req = await this.request('web.get_plugins', []);
|
511
|
-
return req.
|
496
|
+
return req._data;
|
512
497
|
}
|
513
498
|
async getPluginInfo(plugins) {
|
514
499
|
const req = await this.request('web.get_plugin_info', plugins);
|
515
|
-
return req.
|
500
|
+
return req._data;
|
516
501
|
}
|
517
502
|
async enablePlugin(plugins) {
|
518
503
|
const req = await this.request('core.enable_plugin', plugins);
|
519
|
-
return req.
|
504
|
+
return req._data;
|
520
505
|
}
|
521
506
|
async disablePlugin(plugins) {
|
522
507
|
const req = await this.request('core.disable_plugin', plugins);
|
523
|
-
return req.
|
508
|
+
return req._data;
|
524
509
|
}
|
525
510
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
526
511
|
async request(method, params = [], needsAuth = true, autoConnect = true) {
|
@@ -539,19 +524,21 @@ export class Deluge {
|
|
539
524
|
const headers = {
|
540
525
|
Cookie: this._cookie?.cookieString?.(),
|
541
526
|
};
|
542
|
-
const url =
|
543
|
-
const res = await
|
544
|
-
|
527
|
+
const url = joinURL(this.config.baseUrl, this.config.path);
|
528
|
+
const res = await ofetch.raw(url, {
|
529
|
+
method: 'POST',
|
530
|
+
body: JSON.stringify({
|
545
531
|
method,
|
546
532
|
params,
|
547
533
|
id: this._msgId++,
|
548
|
-
},
|
534
|
+
}),
|
549
535
|
headers,
|
550
|
-
retry:
|
551
|
-
timeout:
|
536
|
+
retry: 0,
|
537
|
+
timeout: this.config.timeout,
|
552
538
|
responseType: 'json',
|
553
|
-
|
554
|
-
|
539
|
+
parseResponse: JSON.parse,
|
540
|
+
// @ts-expect-error for some reason agent is not in the type
|
541
|
+
agent: this.config.agent,
|
555
542
|
});
|
556
543
|
const err = res.body?.error ?? (typeof res.body === 'string' && res.body);
|
557
544
|
if (err) {
|
@@ -559,42 +546,6 @@ export class Deluge {
|
|
559
546
|
}
|
560
547
|
return res;
|
561
548
|
}
|
562
|
-
_normalizeTorrentData(id, torrent) {
|
563
|
-
const dateAdded = new Date(torrent.time_added * 1000).toISOString();
|
564
|
-
// normalize state to enum
|
565
|
-
let state = TorrentState.unknown;
|
566
|
-
if (Object.keys(TorrentState).includes(torrent.state.toLowerCase())) {
|
567
|
-
state = TorrentState[torrent.state.toLowerCase()];
|
568
|
-
}
|
569
|
-
const isCompleted = torrent.progress >= 100;
|
570
|
-
const result = {
|
571
|
-
id,
|
572
|
-
name: torrent.name,
|
573
|
-
state,
|
574
|
-
isCompleted,
|
575
|
-
stateMessage: torrent.state,
|
576
|
-
progress: torrent.progress / 100,
|
577
|
-
ratio: torrent.ratio,
|
578
|
-
dateAdded,
|
579
|
-
dateCompleted: undefined,
|
580
|
-
label: torrent.label,
|
581
|
-
savePath: torrent.save_path,
|
582
|
-
uploadSpeed: torrent.upload_payload_rate,
|
583
|
-
downloadSpeed: torrent.download_payload_rate,
|
584
|
-
eta: torrent.eta,
|
585
|
-
queuePosition: torrent.queue + 1,
|
586
|
-
connectedPeers: torrent.num_peers,
|
587
|
-
connectedSeeds: torrent.num_seeds,
|
588
|
-
totalPeers: torrent.total_peers,
|
589
|
-
totalSeeds: torrent.total_seeds,
|
590
|
-
totalSelected: torrent.total_wanted,
|
591
|
-
totalSize: torrent.total_size,
|
592
|
-
totalUploaded: torrent.total_uploaded,
|
593
|
-
totalDownloaded: torrent.total_done,
|
594
|
-
raw: torrent,
|
595
|
-
};
|
596
|
-
return result;
|
597
|
-
}
|
598
549
|
async _validateAuth() {
|
599
550
|
let validAuth = await this.checkSession();
|
600
551
|
if (!validAuth) {
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import { TorrentState } from '@ctrl/shared-torrent';
|
2
|
+
export function normalizeTorrentData(id, torrent) {
|
3
|
+
const dateAdded = new Date(torrent.time_added * 1000).toISOString();
|
4
|
+
// normalize state to enum
|
5
|
+
let state = TorrentState.unknown;
|
6
|
+
if (Object.keys(TorrentState).includes(torrent.state.toLowerCase())) {
|
7
|
+
state = TorrentState[torrent.state.toLowerCase()];
|
8
|
+
}
|
9
|
+
const isCompleted = torrent.progress >= 100;
|
10
|
+
const result = {
|
11
|
+
id,
|
12
|
+
name: torrent.name,
|
13
|
+
state,
|
14
|
+
isCompleted,
|
15
|
+
stateMessage: torrent.state,
|
16
|
+
progress: torrent.progress / 100,
|
17
|
+
ratio: torrent.ratio,
|
18
|
+
dateAdded,
|
19
|
+
dateCompleted: undefined,
|
20
|
+
label: torrent.label,
|
21
|
+
savePath: torrent.save_path,
|
22
|
+
uploadSpeed: torrent.upload_payload_rate,
|
23
|
+
downloadSpeed: torrent.download_payload_rate,
|
24
|
+
eta: torrent.eta,
|
25
|
+
queuePosition: torrent.queue + 1,
|
26
|
+
connectedPeers: torrent.num_peers,
|
27
|
+
connectedSeeds: torrent.num_seeds,
|
28
|
+
totalPeers: torrent.total_peers,
|
29
|
+
totalSeeds: torrent.total_seeds,
|
30
|
+
totalSelected: torrent.total_wanted,
|
31
|
+
totalSize: torrent.total_size,
|
32
|
+
totalUploaded: torrent.total_uploaded,
|
33
|
+
totalDownloaded: torrent.total_done,
|
34
|
+
raw: torrent,
|
35
|
+
};
|
36
|
+
return result;
|
37
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ctrl/deluge",
|
3
|
-
"version": "
|
3
|
+
"version": "5.0.1",
|
4
4
|
"description": "TypeScript api wrapper for deluge using got",
|
5
5
|
"author": "Scott Cooper <scttcper@gmail.com>",
|
6
6
|
"license": "MIT",
|
@@ -28,27 +28,27 @@
|
|
28
28
|
"test:ci": "vitest run --coverage --reporter=default --reporter=junit --outputFile=./junit.xml"
|
29
29
|
},
|
30
30
|
"dependencies": {
|
31
|
-
"@ctrl/magnet-link": "^3.1.
|
32
|
-
"@ctrl/shared-torrent": "^
|
33
|
-
"
|
34
|
-
"
|
35
|
-
"
|
36
|
-
"
|
31
|
+
"@ctrl/magnet-link": "^3.1.2",
|
32
|
+
"@ctrl/shared-torrent": "^5.0.0",
|
33
|
+
"node-fetch-native": "^1.4.1",
|
34
|
+
"ofetch": "^1.3.3",
|
35
|
+
"tough-cookie": "^4.1.3",
|
36
|
+
"ufo": "^1.3.1"
|
37
37
|
},
|
38
38
|
"devDependencies": {
|
39
|
-
"@ctrl/eslint-config": "
|
40
|
-
"@sindresorhus/tsconfig": "
|
41
|
-
"@types/node": "
|
42
|
-
"@types/tough-cookie": "4.0.
|
43
|
-
"@vitest/coverage-
|
44
|
-
"
|
45
|
-
"
|
46
|
-
"
|
47
|
-
"
|
48
|
-
"vitest": "0.29.2"
|
39
|
+
"@ctrl/eslint-config": "4.0.9",
|
40
|
+
"@sindresorhus/tsconfig": "5.0.0",
|
41
|
+
"@types/node": "20.8.10",
|
42
|
+
"@types/tough-cookie": "4.0.4",
|
43
|
+
"@vitest/coverage-v8": "0.34.6",
|
44
|
+
"p-wait-for": "5.0.2",
|
45
|
+
"typedoc": "0.25.3",
|
46
|
+
"typescript": "5.2.2",
|
47
|
+
"vitest": "0.34.6"
|
49
48
|
},
|
50
49
|
"publishConfig": {
|
51
|
-
"access": "public"
|
50
|
+
"access": "public",
|
51
|
+
"provenance": true
|
52
52
|
},
|
53
53
|
"release": {
|
54
54
|
"branches": [
|
@@ -56,6 +56,6 @@
|
|
56
56
|
]
|
57
57
|
},
|
58
58
|
"engines": {
|
59
|
-
"node": ">=
|
59
|
+
"node": ">=18"
|
60
60
|
}
|
61
61
|
}
|