@ctrl/deluge 3.4.1 → 4.1.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.
- package/dist/{index.d.ts → src/deluge.d.ts} +2 -2
- package/dist/{index.js → src/deluge.js} +70 -48
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +2 -0
- package/dist/{types.d.ts → src/types.d.ts} +0 -0
- package/dist/src/types.js +1 -0
- package/package.json +27 -35
- package/dist/types.js +0 -2
@@ -1,7 +1,7 @@
|
|
1
|
-
/// <reference types="node" />
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
2
2
|
import { Response } from 'got';
|
3
3
|
import { AddTorrentOptions as NormalizedAddTorrentOptions, AllClientData, NormalizedTorrent, TorrentClient, TorrentSettings } from '@ctrl/shared-torrent';
|
4
|
-
import { AddTorrentOptions, BooleanStatus, ConfigResponse, DefaultResponse, DelugeSettings, GetHostsResponse, GetHostStatusResponse, ListMethods, PluginInfo, PluginsListResponse, StringStatus, TorrentFiles, TorrentInfo, TorrentListResponse, TorrentOptions, TorrentStatus, Tracker, UploadResponse
|
4
|
+
import { 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 {
|
6
6
|
config: TorrentSettings;
|
7
7
|
private _msgId;
|
@@ -1,24 +1,37 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
const got_1 = __importDefault(require("got"));
|
10
|
-
const tough_cookie_1 = require("tough-cookie");
|
11
|
-
const url_join_1 = require("@ctrl/url-join");
|
12
|
-
const shared_torrent_1 = require("@ctrl/shared-torrent");
|
1
|
+
import { existsSync } from 'fs';
|
2
|
+
import { File, FormData } from 'formdata-node';
|
3
|
+
import { fileFromPath } from 'formdata-node/file-from-path';
|
4
|
+
import got from 'got';
|
5
|
+
import { Cookie } from 'tough-cookie';
|
6
|
+
import { magnetDecode } from '@ctrl/magnet-link';
|
7
|
+
import { TorrentState, } from '@ctrl/shared-torrent';
|
8
|
+
import { urlJoin } from '@ctrl/url-join';
|
13
9
|
const defaults = {
|
14
10
|
baseUrl: 'http://localhost:8112/',
|
15
11
|
path: '/json',
|
16
12
|
password: 'deluge',
|
17
13
|
timeout: 5000,
|
18
14
|
};
|
19
|
-
class Deluge {
|
15
|
+
export class Deluge {
|
20
16
|
constructor(options = {}) {
|
21
|
-
this
|
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
|
+
});
|
22
35
|
this.config = { ...defaults, ...options };
|
23
36
|
}
|
24
37
|
resetSession() {
|
@@ -76,7 +89,6 @@ class Deluge {
|
|
76
89
|
* @returns true if valid
|
77
90
|
*/
|
78
91
|
async checkSession() {
|
79
|
-
var _a;
|
80
92
|
// cookie is missing or expires in x seconds
|
81
93
|
if (this._cookie) {
|
82
94
|
// eslint-disable-next-line new-cap
|
@@ -89,11 +101,11 @@ class Deluge {
|
|
89
101
|
if (this._cookie) {
|
90
102
|
try {
|
91
103
|
const check = await this.request('auth.check_session', undefined, false);
|
92
|
-
if (
|
104
|
+
if (check?.body?.result) {
|
93
105
|
return true;
|
94
106
|
}
|
95
107
|
}
|
96
|
-
catch
|
108
|
+
catch {
|
97
109
|
// do nothing
|
98
110
|
}
|
99
111
|
}
|
@@ -110,7 +122,7 @@ class Deluge {
|
|
110
122
|
if (!res.body.result || !res.headers || !res.headers['set-cookie']) {
|
111
123
|
throw new Error('Auth failed, incorrect password');
|
112
124
|
}
|
113
|
-
this._cookie =
|
125
|
+
this._cookie = Cookie.parse(res.headers['set-cookie'][0]);
|
114
126
|
return true;
|
115
127
|
}
|
116
128
|
/**
|
@@ -152,26 +164,28 @@ class Deluge {
|
|
152
164
|
if (!isConnected) {
|
153
165
|
await this.connect();
|
154
166
|
}
|
155
|
-
const form = new
|
167
|
+
const form = new FormData();
|
168
|
+
const type = { type: 'application/x-bittorrent' };
|
156
169
|
if (typeof torrent === 'string') {
|
157
|
-
if (
|
158
|
-
|
170
|
+
if (existsSync(torrent)) {
|
171
|
+
const file = await fileFromPath(torrent, 'temp.torrent', type);
|
172
|
+
form.set('file', file);
|
159
173
|
}
|
160
174
|
else {
|
161
|
-
form.
|
175
|
+
form.set('file', new File([Buffer.from(torrent, 'base64')], 'file.torrent', type));
|
162
176
|
}
|
163
177
|
}
|
164
178
|
else {
|
165
|
-
|
179
|
+
const file = new File([torrent], 'torrent', type);
|
180
|
+
form.set('file', file);
|
166
181
|
}
|
167
|
-
const url =
|
168
|
-
const res = await
|
169
|
-
headers: form.getHeaders(),
|
182
|
+
const url = urlJoin(this.config.baseUrl, '/upload');
|
183
|
+
const res = await got.post(url, {
|
170
184
|
body: form,
|
171
|
-
retry: 0,
|
185
|
+
retry: { limit: 0 },
|
186
|
+
timeout: { request: this.config.timeout },
|
172
187
|
// allow proxy agent
|
173
|
-
agent: this.config.agent,
|
174
|
-
timeout: this.config.timeout,
|
188
|
+
...(this.config.agent ? { agent: this.config.agent } : {}),
|
175
189
|
});
|
176
190
|
// repsonse is json but in a string, cannot use native got.json()
|
177
191
|
return JSON.parse(res.body);
|
@@ -232,11 +246,21 @@ class Deluge {
|
|
232
246
|
if (options.startPaused) {
|
233
247
|
torrentOptions.add_paused = true;
|
234
248
|
}
|
235
|
-
|
236
|
-
|
249
|
+
let torrentHash;
|
250
|
+
if (typeof torrent === 'string' && torrent.startsWith('magnet:')) {
|
251
|
+
torrentHash = magnetDecode(torrent).infoHash;
|
252
|
+
if (!torrentHash) {
|
253
|
+
throw new Error('Magnet did not contain hash');
|
254
|
+
}
|
255
|
+
await this.addTorrentMagnet(torrent, torrentOptions);
|
256
|
+
}
|
257
|
+
else {
|
258
|
+
if (!Buffer.isBuffer(torrent)) {
|
259
|
+
torrent = Buffer.from(torrent);
|
260
|
+
}
|
261
|
+
const res = await this.addTorrent(torrent, torrentOptions);
|
262
|
+
torrentHash = res.result[0][1];
|
237
263
|
}
|
238
|
-
const res = await this.addTorrent(torrent, torrentOptions);
|
239
|
-
const torrentHash = res.result[0][1];
|
240
264
|
if (options.label) {
|
241
265
|
// sets the label but it might not set the label right away
|
242
266
|
// sometimes takes a few seconds for label to reflect in results
|
@@ -286,7 +310,7 @@ class Deluge {
|
|
286
310
|
}
|
287
311
|
// update current password to new password
|
288
312
|
this.config.password = password;
|
289
|
-
this._cookie =
|
313
|
+
this._cookie = Cookie.parse(res.headers['set-cookie'][0]);
|
290
314
|
return res.body;
|
291
315
|
}
|
292
316
|
async getAllData() {
|
@@ -499,7 +523,6 @@ class Deluge {
|
|
499
523
|
}
|
500
524
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
501
525
|
async request(method, params = [], needsAuth = true, autoConnect = true) {
|
502
|
-
var _a, _b, _c, _d;
|
503
526
|
if (this._msgId === 4096) {
|
504
527
|
this._msgId = 0;
|
505
528
|
}
|
@@ -513,23 +536,23 @@ class Deluge {
|
|
513
536
|
}
|
514
537
|
}
|
515
538
|
const headers = {
|
516
|
-
Cookie:
|
539
|
+
Cookie: this._cookie?.cookieString?.(),
|
517
540
|
};
|
518
|
-
const url =
|
519
|
-
const res = await
|
541
|
+
const url = urlJoin(this.config.baseUrl, this.config.path);
|
542
|
+
const res = await got.post(url, {
|
520
543
|
json: {
|
521
544
|
method,
|
522
545
|
params,
|
523
546
|
id: this._msgId++,
|
524
547
|
},
|
525
548
|
headers,
|
526
|
-
retry: 0,
|
527
|
-
|
528
|
-
agent: this.config.agent,
|
529
|
-
timeout: this.config.timeout,
|
549
|
+
retry: { limit: 0 },
|
550
|
+
timeout: { request: this.config.timeout },
|
530
551
|
responseType: 'json',
|
552
|
+
// allow proxy agent
|
553
|
+
...(this.config.agent ? { agent: this.config.agent } : {}),
|
531
554
|
});
|
532
|
-
const err =
|
555
|
+
const err = res.body?.error ?? (typeof res.body === 'string' && res.body);
|
533
556
|
if (err) {
|
534
557
|
throw new Error(err.message || err);
|
535
558
|
}
|
@@ -538,9 +561,9 @@ class Deluge {
|
|
538
561
|
_normalizeTorrentData(id, torrent) {
|
539
562
|
const dateAdded = new Date(torrent.time_added * 1000).toISOString();
|
540
563
|
// normalize state to enum
|
541
|
-
let state =
|
542
|
-
if (Object.keys(
|
543
|
-
state =
|
564
|
+
let state = TorrentState.unknown;
|
565
|
+
if (Object.keys(TorrentState).includes(torrent.state.toLowerCase())) {
|
566
|
+
state = TorrentState[torrent.state.toLowerCase()];
|
544
567
|
}
|
545
568
|
const isCompleted = torrent.progress >= 100;
|
546
569
|
const result = {
|
@@ -549,7 +572,7 @@ class Deluge {
|
|
549
572
|
state,
|
550
573
|
isCompleted,
|
551
574
|
stateMessage: torrent.state,
|
552
|
-
progress: torrent.progress,
|
575
|
+
progress: torrent.progress / 100,
|
553
576
|
ratio: torrent.ratio,
|
554
577
|
dateAdded,
|
555
578
|
dateCompleted: undefined,
|
@@ -580,4 +603,3 @@ class Deluge {
|
|
580
603
|
}
|
581
604
|
}
|
582
605
|
}
|
583
|
-
exports.Deluge = Deluge;
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ctrl/deluge",
|
3
|
-
"version": "
|
3
|
+
"version": "4.1.0",
|
4
4
|
"description": "TypeScript api wrapper for deluge using got",
|
5
5
|
"author": "Scott Cooper <scttcper@gmail.com>",
|
6
6
|
"license": "MIT",
|
@@ -10,59 +10,51 @@
|
|
10
10
|
"deluge",
|
11
11
|
"typescript"
|
12
12
|
],
|
13
|
-
"
|
14
|
-
"
|
13
|
+
"type": "module",
|
14
|
+
"main": "./dist/src/index.js",
|
15
|
+
"typings": "./dist/src/index.d.ts",
|
15
16
|
"files": [
|
16
|
-
"dist"
|
17
|
+
"dist/src"
|
17
18
|
],
|
18
19
|
"sideEffects": false,
|
19
20
|
"scripts": {
|
20
21
|
"lint": "eslint --ext .js,.ts, .",
|
21
22
|
"lint:fix": "eslint --fix --ext .js,.ts, .",
|
22
23
|
"prepare": "npm run build",
|
23
|
-
"build": "tsc
|
24
|
+
"build": "tsc",
|
24
25
|
"build:docs": "typedoc",
|
25
|
-
"test": "
|
26
|
-
"test:watch": "
|
27
|
-
"test:ci": "
|
26
|
+
"test": "vitest run",
|
27
|
+
"test:watch": "vitest",
|
28
|
+
"test:ci": "vitest run --coverage --reporter=default --reporter=junit --outputFile=./junit.xml"
|
28
29
|
},
|
29
30
|
"dependencies": {
|
30
|
-
"@ctrl/
|
31
|
-
"@ctrl/
|
32
|
-
"
|
33
|
-
"
|
31
|
+
"@ctrl/magnet-link": "^3.1.1",
|
32
|
+
"@ctrl/shared-torrent": "^4.1.1",
|
33
|
+
"@ctrl/url-join": "^2.0.0",
|
34
|
+
"formdata-node": "^4.3.2",
|
35
|
+
"got": "^12.1.0",
|
34
36
|
"tough-cookie": "^4.0.0"
|
35
37
|
},
|
36
38
|
"devDependencies": {
|
37
|
-
"@
|
38
|
-
"@
|
39
|
-
"@
|
40
|
-
"@
|
41
|
-
"
|
42
|
-
"
|
43
|
-
"
|
44
|
-
"
|
45
|
-
"
|
46
|
-
"typescript": "4.2.4"
|
47
|
-
},
|
48
|
-
"jest": {
|
49
|
-
"testEnvironment": "node"
|
50
|
-
},
|
51
|
-
"babel": {
|
52
|
-
"presets": [
|
53
|
-
"@babel/preset-typescript"
|
54
|
-
],
|
55
|
-
"plugins": [
|
56
|
-
"@babel/plugin-transform-modules-commonjs"
|
57
|
-
]
|
39
|
+
"@ctrl/eslint-config": "3.4.4",
|
40
|
+
"@sindresorhus/tsconfig": "3.0.1",
|
41
|
+
"@types/node": "17.0.40",
|
42
|
+
"@types/tough-cookie": "4.0.2",
|
43
|
+
"c8": "7.11.3",
|
44
|
+
"p-wait-for": "4.1.0",
|
45
|
+
"typedoc": "0.22.17",
|
46
|
+
"typescript": "4.7.3",
|
47
|
+
"vitest": "0.14.1"
|
58
48
|
},
|
59
49
|
"publishConfig": {
|
60
50
|
"access": "public"
|
61
51
|
},
|
62
52
|
"release": {
|
63
|
-
"
|
53
|
+
"branches": [
|
54
|
+
"master"
|
55
|
+
]
|
64
56
|
},
|
65
57
|
"engines": {
|
66
|
-
"node": ">=
|
58
|
+
"node": ">=14.16"
|
67
59
|
}
|
68
60
|
}
|
package/dist/types.js
DELETED