@ctrl/transmission 2.4.1 → 4.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.
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +2 -0
- package/dist/{transmission.d.ts → src/transmission.d.ts} +17 -16
- package/dist/{transmission.js → src/transmission.js} +72 -55
- package/dist/{types.d.ts → src/types.d.ts} +8 -3
- package/dist/src/types.js +1 -0
- package/dist/test/transmission.spec.d.ts +1 -0
- package/dist/test/transmission.spec.js +130 -0
- package/dist/vitest.config.d.ts +2 -0
- package/dist/vitest.config.js +7 -0
- package/package.json +23 -31
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -14
- package/dist/types.js +0 -2
@@ -1,38 +1,38 @@
|
|
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, AddTorrentResponse, DefaultResponse, FreeSpaceResponse, GetTorrentRepsonse, RenamePathOptions, SessionArguments, SessionResponse, SetTorrentOptions
|
4
|
+
import { AddTorrentOptions, AddTorrentResponse, DefaultResponse, FreeSpaceResponse, GetTorrentRepsonse, NormalizedTorrentIds, RenamePathOptions, SessionArguments, SessionResponse, SetTorrentOptions } from './types.js';
|
5
5
|
export declare class Transmission implements TorrentClient {
|
6
6
|
config: TorrentSettings;
|
7
7
|
sessionId?: string;
|
8
8
|
constructor(options?: Partial<TorrentSettings>);
|
9
9
|
getSession(): Promise<SessionResponse>;
|
10
10
|
setSession(args: Partial<SessionArguments>): Promise<SessionResponse>;
|
11
|
-
queueTop(
|
12
|
-
queueBottom(
|
13
|
-
queueUp(
|
14
|
-
queueDown(
|
11
|
+
queueTop(id: NormalizedTorrentIds): Promise<DefaultResponse>;
|
12
|
+
queueBottom(id: NormalizedTorrentIds): Promise<DefaultResponse>;
|
13
|
+
queueUp(id: NormalizedTorrentIds): Promise<DefaultResponse>;
|
14
|
+
queueDown(id: NormalizedTorrentIds): Promise<DefaultResponse>;
|
15
15
|
freeSpace(path?: string): Promise<FreeSpaceResponse>;
|
16
|
-
pauseTorrent(
|
17
|
-
resumeTorrent(
|
18
|
-
verifyTorrent(
|
16
|
+
pauseTorrent(id: NormalizedTorrentIds): Promise<DefaultResponse>;
|
17
|
+
resumeTorrent(id: NormalizedTorrentIds): Promise<DefaultResponse>;
|
18
|
+
verifyTorrent(id: NormalizedTorrentIds): Promise<DefaultResponse>;
|
19
19
|
/**
|
20
20
|
* ask tracker for more peers
|
21
21
|
*/
|
22
|
-
reannounceTorrent(
|
23
|
-
moveTorrent(
|
22
|
+
reannounceTorrent(id: NormalizedTorrentIds): Promise<DefaultResponse>;
|
23
|
+
moveTorrent(id: NormalizedTorrentIds, location: string): Promise<DefaultResponse>;
|
24
24
|
/**
|
25
25
|
* Torrent Mutators
|
26
26
|
*/
|
27
|
-
setTorrent(
|
27
|
+
setTorrent(id: NormalizedTorrentIds, options?: Partial<SetTorrentOptions>): Promise<DefaultResponse>;
|
28
28
|
/**
|
29
29
|
* Renaming a Torrent's Path
|
30
30
|
*/
|
31
|
-
renamePath(
|
31
|
+
renamePath(id: NormalizedTorrentIds, options?: Partial<RenamePathOptions>): Promise<DefaultResponse>;
|
32
32
|
/**
|
33
33
|
* Removing a Torrent
|
34
34
|
*/
|
35
|
-
removeTorrent(
|
35
|
+
removeTorrent(id: NormalizedTorrentIds, removeData?: boolean): Promise<AddTorrentResponse>;
|
36
36
|
/**
|
37
37
|
* An alias for {@link Transmission.addMagnet}
|
38
38
|
*/
|
@@ -50,9 +50,10 @@ export declare class Transmission implements TorrentClient {
|
|
50
50
|
*/
|
51
51
|
addTorrent(torrent: string | Buffer, options?: Partial<AddTorrentOptions>): Promise<AddTorrentResponse>;
|
52
52
|
normalizedAddTorrent(torrent: string | Buffer, options?: Partial<NormalizedAddTorrentOptions>): Promise<NormalizedTorrent>;
|
53
|
-
getTorrent(id:
|
53
|
+
getTorrent(id: NormalizedTorrentIds): Promise<NormalizedTorrent>;
|
54
54
|
getAllData(): Promise<AllClientData>;
|
55
|
-
listTorrents(
|
55
|
+
listTorrents(id?: NormalizedTorrentIds, additionalFields?: string[]): Promise<GetTorrentRepsonse>;
|
56
56
|
request<T>(method: string, args?: any): Promise<Response<T>>;
|
57
|
+
private _handleNormalizedIds;
|
57
58
|
private _normalizeTorrentData;
|
58
59
|
}
|
@@ -1,13 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
};
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.Transmission = void 0;
|
7
|
-
const fs_1 = require("fs");
|
8
|
-
const got_1 = __importDefault(require("got"));
|
9
|
-
const shared_torrent_1 = require("@ctrl/shared-torrent");
|
10
|
-
const url_join_1 = require("@ctrl/url-join");
|
1
|
+
import { existsSync, readFileSync } from 'fs';
|
2
|
+
import got from 'got';
|
3
|
+
import { TorrentState, } from '@ctrl/shared-torrent';
|
4
|
+
import { urlJoin } from '@ctrl/url-join';
|
11
5
|
const defaults = {
|
12
6
|
baseUrl: 'http://localhost:9091/',
|
13
7
|
path: '/transmission/rpc',
|
@@ -15,8 +9,20 @@ const defaults = {
|
|
15
9
|
password: '',
|
16
10
|
timeout: 5000,
|
17
11
|
};
|
18
|
-
class Transmission {
|
12
|
+
export class Transmission {
|
19
13
|
constructor(options = {}) {
|
14
|
+
Object.defineProperty(this, "config", {
|
15
|
+
enumerable: true,
|
16
|
+
configurable: true,
|
17
|
+
writable: true,
|
18
|
+
value: void 0
|
19
|
+
});
|
20
|
+
Object.defineProperty(this, "sessionId", {
|
21
|
+
enumerable: true,
|
22
|
+
configurable: true,
|
23
|
+
writable: true,
|
24
|
+
value: void 0
|
25
|
+
});
|
20
26
|
this.config = { ...defaults, ...options };
|
21
27
|
}
|
22
28
|
async getSession() {
|
@@ -27,19 +33,23 @@ class Transmission {
|
|
27
33
|
const res = await this.request('session-set', args);
|
28
34
|
return res.body;
|
29
35
|
}
|
30
|
-
async queueTop(
|
36
|
+
async queueTop(id) {
|
37
|
+
const ids = this._handleNormalizedIds(id);
|
31
38
|
const res = await this.request('queue-move-top', { ids });
|
32
39
|
return res.body;
|
33
40
|
}
|
34
|
-
async queueBottom(
|
41
|
+
async queueBottom(id) {
|
42
|
+
const ids = this._handleNormalizedIds(id);
|
35
43
|
const res = await this.request('queue-move-bottom', { ids });
|
36
44
|
return res.body;
|
37
45
|
}
|
38
|
-
async queueUp(
|
46
|
+
async queueUp(id) {
|
47
|
+
const ids = this._handleNormalizedIds(id);
|
39
48
|
const res = await this.request('queue-move-up', { ids });
|
40
49
|
return res.body;
|
41
50
|
}
|
42
|
-
async queueDown(
|
51
|
+
async queueDown(id) {
|
52
|
+
const ids = this._handleNormalizedIds(id);
|
43
53
|
const res = await this.request('queue-move-down', { ids });
|
44
54
|
return res.body;
|
45
55
|
}
|
@@ -47,26 +57,31 @@ class Transmission {
|
|
47
57
|
const res = await this.request('free-space', { path });
|
48
58
|
return res.body;
|
49
59
|
}
|
50
|
-
async pauseTorrent(
|
60
|
+
async pauseTorrent(id) {
|
61
|
+
const ids = this._handleNormalizedIds(id);
|
51
62
|
const res = await this.request('torrent-stop', { ids });
|
52
63
|
return res.body;
|
53
64
|
}
|
54
|
-
async resumeTorrent(
|
65
|
+
async resumeTorrent(id) {
|
66
|
+
const ids = this._handleNormalizedIds(id);
|
55
67
|
const res = await this.request('torrent-start', { ids });
|
56
68
|
return res.body;
|
57
69
|
}
|
58
|
-
async verifyTorrent(
|
70
|
+
async verifyTorrent(id) {
|
71
|
+
const ids = this._handleNormalizedIds(id);
|
59
72
|
const res = await this.request('torrent-verify', { ids });
|
60
73
|
return res.body;
|
61
74
|
}
|
62
75
|
/**
|
63
76
|
* ask tracker for more peers
|
64
77
|
*/
|
65
|
-
async reannounceTorrent(
|
78
|
+
async reannounceTorrent(id) {
|
79
|
+
const ids = this._handleNormalizedIds(id);
|
66
80
|
const res = await this.request('torrent-reannounce', { ids });
|
67
81
|
return res.body;
|
68
82
|
}
|
69
|
-
async moveTorrent(
|
83
|
+
async moveTorrent(id, location) {
|
84
|
+
const ids = this._handleNormalizedIds(id);
|
70
85
|
const res = await this.request('torrent-set-location', {
|
71
86
|
ids,
|
72
87
|
move: true,
|
@@ -77,7 +92,8 @@ class Transmission {
|
|
77
92
|
/**
|
78
93
|
* Torrent Mutators
|
79
94
|
*/
|
80
|
-
async setTorrent(
|
95
|
+
async setTorrent(id, options = {}) {
|
96
|
+
const ids = this._handleNormalizedIds(id);
|
81
97
|
options.ids = ids;
|
82
98
|
const res = await this.request('torrent-set', options);
|
83
99
|
return res.body;
|
@@ -85,7 +101,8 @@ class Transmission {
|
|
85
101
|
/**
|
86
102
|
* Renaming a Torrent's Path
|
87
103
|
*/
|
88
|
-
async renamePath(
|
104
|
+
async renamePath(id, options = {}) {
|
105
|
+
const ids = this._handleNormalizedIds(id);
|
89
106
|
options.ids = ids;
|
90
107
|
const res = await this.request('torrent-rename-path', options);
|
91
108
|
return res.body;
|
@@ -93,7 +110,8 @@ class Transmission {
|
|
93
110
|
/**
|
94
111
|
* Removing a Torrent
|
95
112
|
*/
|
96
|
-
async removeTorrent(
|
113
|
+
async removeTorrent(id, removeData = true) {
|
114
|
+
const ids = this._handleNormalizedIds(id);
|
97
115
|
const res = await this.request('torrent-remove', {
|
98
116
|
ids,
|
99
117
|
'delete-local-data': removeData,
|
@@ -133,8 +151,8 @@ class Transmission {
|
|
133
151
|
...options,
|
134
152
|
};
|
135
153
|
if (typeof torrent === 'string') {
|
136
|
-
args.metainfo =
|
137
|
-
? Buffer.from(
|
154
|
+
args.metainfo = existsSync(torrent)
|
155
|
+
? Buffer.from(readFileSync(torrent)).toString('base64')
|
138
156
|
: Buffer.from(torrent, 'base64').toString('base64');
|
139
157
|
}
|
140
158
|
else {
|
@@ -152,12 +170,11 @@ class Transmission {
|
|
152
170
|
torrent = Buffer.from(torrent);
|
153
171
|
}
|
154
172
|
const res = await this.addTorrent(torrent, torrentOptions);
|
155
|
-
const
|
173
|
+
const torrentHash = [res.arguments['torrent-added'].hashString];
|
156
174
|
if (options.label) {
|
157
|
-
|
158
|
-
console.log(res);
|
175
|
+
await this.setTorrent(torrentHash, { labels: [options.label] });
|
159
176
|
}
|
160
|
-
return this.getTorrent(
|
177
|
+
return this.getTorrent(torrentHash);
|
161
178
|
}
|
162
179
|
async getTorrent(id) {
|
163
180
|
const result = await this.listTorrents(id);
|
@@ -187,7 +204,7 @@ class Transmission {
|
|
187
204
|
};
|
188
205
|
return results;
|
189
206
|
}
|
190
|
-
async listTorrents(
|
207
|
+
async listTorrents(id, additionalFields = []) {
|
191
208
|
const fields = [
|
192
209
|
'id',
|
193
210
|
'addedDate',
|
@@ -250,18 +267,14 @@ class Transmission {
|
|
250
267
|
...additionalFields,
|
251
268
|
];
|
252
269
|
const args = { fields };
|
253
|
-
if (
|
270
|
+
if (id) {
|
271
|
+
const ids = this._handleNormalizedIds(id);
|
254
272
|
args.ids = ids;
|
255
273
|
}
|
256
274
|
const res = await this.request('torrent-get', args);
|
257
275
|
return res.body;
|
258
276
|
}
|
259
|
-
// async getTorrent(id: TorrentIds): Promise<NormalizedTorrent> {
|
260
|
-
// const torrent: any = {};
|
261
|
-
// return torrent;
|
262
|
-
// }
|
263
277
|
async request(method, args = {}) {
|
264
|
-
var _a, _b, _c;
|
265
278
|
if (!this.sessionId && method !== 'session-get') {
|
266
279
|
await this.getSession();
|
267
280
|
}
|
@@ -269,58 +282,64 @@ class Transmission {
|
|
269
282
|
'X-Transmission-Session-Id': this.sessionId,
|
270
283
|
};
|
271
284
|
if (this.config.username || this.config.password) {
|
272
|
-
const str = `${
|
285
|
+
const str = `${this.config.username ?? ''}:${this.config.password ?? ''}`;
|
273
286
|
headers.Authorization = 'Basic ' + Buffer.from(str).toString('base64');
|
274
287
|
}
|
275
|
-
const url =
|
288
|
+
const url = urlJoin(this.config.baseUrl, this.config.path);
|
276
289
|
try {
|
277
|
-
const res = await
|
290
|
+
const res = await got.post(url, {
|
278
291
|
json: {
|
279
292
|
method,
|
280
293
|
arguments: args,
|
281
294
|
},
|
282
295
|
headers,
|
283
|
-
retry: 0,
|
296
|
+
retry: { limit: 0 },
|
284
297
|
// allow proxy agent
|
285
|
-
|
286
|
-
timeout: this.config.timeout,
|
298
|
+
timeout: { request: this.config.timeout },
|
287
299
|
responseType: 'json',
|
300
|
+
...(this.config.agent ? { agent: this.config.agent } : {}),
|
288
301
|
});
|
289
302
|
return res;
|
290
303
|
}
|
291
304
|
catch (error) {
|
292
|
-
if (
|
305
|
+
if (error?.response?.statusCode === 409) {
|
293
306
|
this.sessionId = error.response.headers['x-transmission-session-id'];
|
294
307
|
// eslint-disable-next-line no-return-await
|
295
308
|
return await this.request(method, args);
|
296
309
|
}
|
310
|
+
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
297
311
|
throw error;
|
298
312
|
}
|
299
313
|
}
|
314
|
+
_handleNormalizedIds(ids) {
|
315
|
+
if (typeof ids === 'string' && ids !== 'recently-active') {
|
316
|
+
return [ids];
|
317
|
+
}
|
318
|
+
return ids;
|
319
|
+
}
|
300
320
|
_normalizeTorrentData(torrent) {
|
301
|
-
var _a;
|
302
321
|
const dateAdded = new Date(torrent.addedDate * 1000).toISOString();
|
303
322
|
const dateCompleted = new Date(torrent.doneDate * 1000).toISOString();
|
304
323
|
// normalize state to enum
|
305
324
|
// https://github.com/transmission/transmission/blob/c11f2870fd18ff781ca06ce84b6d43541f3293dd/web/javascript/torrent.js#L18
|
306
|
-
let state =
|
325
|
+
let state = TorrentState.unknown;
|
307
326
|
if (torrent.status === 6) {
|
308
|
-
state =
|
327
|
+
state = TorrentState.seeding;
|
309
328
|
}
|
310
329
|
else if (torrent.status === 4) {
|
311
|
-
state =
|
330
|
+
state = TorrentState.downloading;
|
312
331
|
}
|
313
332
|
else if (torrent.status === 0) {
|
314
|
-
state =
|
333
|
+
state = TorrentState.paused;
|
315
334
|
}
|
316
335
|
else if (torrent.status === 2) {
|
317
|
-
state =
|
336
|
+
state = TorrentState.checking;
|
318
337
|
}
|
319
338
|
else if (torrent.status === 3 || torrent.status === 5) {
|
320
|
-
state =
|
339
|
+
state = TorrentState.queued;
|
321
340
|
}
|
322
|
-
|
323
|
-
id: torrent.
|
341
|
+
return {
|
342
|
+
id: torrent.hashString,
|
324
343
|
name: torrent.name,
|
325
344
|
state,
|
326
345
|
isCompleted: torrent.leftUntilDone < 1,
|
@@ -329,7 +348,7 @@ class Transmission {
|
|
329
348
|
ratio: torrent.uploadRatio,
|
330
349
|
dateAdded,
|
331
350
|
dateCompleted,
|
332
|
-
label:
|
351
|
+
label: torrent.labels?.length ? torrent.labels[0] : undefined,
|
333
352
|
savePath: torrent.downloadDir,
|
334
353
|
uploadSpeed: torrent.rateUpload,
|
335
354
|
downloadSpeed: torrent.rateDownload,
|
@@ -344,7 +363,5 @@ class Transmission {
|
|
344
363
|
totalUploaded: torrent.uploadedEver,
|
345
364
|
totalDownloaded: torrent.downloadedEver,
|
346
365
|
};
|
347
|
-
return result;
|
348
366
|
}
|
349
367
|
}
|
350
|
-
exports.Transmission = Transmission;
|
@@ -39,12 +39,17 @@ export interface FreeSpaceResponse extends DefaultResponse {
|
|
39
39
|
/**
|
40
40
|
* "ids", which specifies which torrents to use.
|
41
41
|
* All torrents are used if the "ids" argument is omitted.
|
42
|
+
*
|
42
43
|
* "ids" should be one of the following:
|
43
|
-
*
|
44
|
-
*
|
45
|
-
*
|
44
|
+
* 1. an integer referring to a torrent id
|
45
|
+
* 2. a list of torrent id numbers, sha1 hash strings, or both
|
46
|
+
* 3. a string, "recently-active", for recently-active torrents
|
46
47
|
*/
|
47
48
|
export declare type TorrentIds = number | 'recently-active' | Array<number | string>;
|
49
|
+
/**
|
50
|
+
* Allows the user to pass a single hash, this will be converted to an array
|
51
|
+
*/
|
52
|
+
export declare type NormalizedTorrentIds = TorrentIds | string;
|
48
53
|
export interface GetTorrentRepsonse extends DefaultResponse {
|
49
54
|
arguments: {
|
50
55
|
removed: Torrent[];
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,130 @@
|
|
1
|
+
import fs from 'fs';
|
2
|
+
import path from 'path';
|
3
|
+
import pWaitFor from 'p-wait-for';
|
4
|
+
import { afterEach, describe, expect, it } from 'vitest';
|
5
|
+
import { TorrentState } from '@ctrl/shared-torrent';
|
6
|
+
import { Transmission } from '../src/index.js';
|
7
|
+
const baseUrl = 'http://localhost:9091/';
|
8
|
+
const torrentName = 'ubuntu-18.04.1-desktop-amd64.iso';
|
9
|
+
const torrentFile = path.join(__dirname, '/ubuntu-18.04.1-desktop-amd64.iso.torrent');
|
10
|
+
async function setupTorrent(transmission) {
|
11
|
+
const res = await transmission.addTorrent(torrentFile);
|
12
|
+
await pWaitFor(async () => {
|
13
|
+
const r = await transmission.listTorrents(undefined, ['id']);
|
14
|
+
return r.arguments.torrents.length === 1;
|
15
|
+
}, { timeout: 10000, interval: 200 });
|
16
|
+
return res.arguments['torrent-added'].hashString;
|
17
|
+
}
|
18
|
+
describe('Transmission', () => {
|
19
|
+
afterEach(async () => {
|
20
|
+
const transmission = new Transmission({ baseUrl });
|
21
|
+
const res = await transmission.listTorrents();
|
22
|
+
// clean up all torrents
|
23
|
+
for (const torrent of res.arguments.torrents) {
|
24
|
+
// eslint-disable-next-line no-await-in-loop
|
25
|
+
await transmission.removeTorrent(torrent.id, false);
|
26
|
+
}
|
27
|
+
});
|
28
|
+
it('should be instantiable', () => {
|
29
|
+
const transmission = new Transmission({ baseUrl });
|
30
|
+
expect(transmission).toBeTruthy();
|
31
|
+
});
|
32
|
+
it('should add torrent from file path string', async () => {
|
33
|
+
const transmission = new Transmission({ baseUrl });
|
34
|
+
const res = await transmission.addTorrent(torrentFile);
|
35
|
+
expect(res.result).toBe('success');
|
36
|
+
});
|
37
|
+
it('should add magnet link', async () => {
|
38
|
+
const magnet = 'magnet:?xt=urn:btih:B0B81206633C42874173D22E564D293DAEFC45E2&dn=Ubuntu+11+10+Alternate+Amd64+Iso&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969%2Fannounce&tr=udp%3A%2F%2F9.rarbg.to%3A2710%2Fannounce&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337%2Fannounce&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969%2Fannounce&tr=udp%3A%2F%2Ftracker.open-internet.nl%3A6969%2Fannounce&tr=udp%3A%2F%2Fopen.demonii.si%3A1337%2Fannounce&tr=udp%3A%2F%2Ftracker.pirateparty.gr%3A6969%2Fannounce&tr=udp%3A%2F%2Fdenis.stalker.upeer.me%3A6969%2Fannounce&tr=udp%3A%2F%2Fp4p.arenabg.com%3A1337%2Fannounce&tr=udp%3A%2F%2Fexodus.desync.com%3A6969%2Fannounce';
|
39
|
+
const client = new Transmission({ baseUrl });
|
40
|
+
const res = await client.addMagnet(magnet);
|
41
|
+
expect(res.result).toBe('success');
|
42
|
+
});
|
43
|
+
it('should add torrent from file buffer', async () => {
|
44
|
+
const transmission = new Transmission({ baseUrl });
|
45
|
+
const res = await transmission.addTorrent(fs.readFileSync(torrentFile));
|
46
|
+
expect(res.result).toBe('success');
|
47
|
+
});
|
48
|
+
it('should add torrent from file contents base64', async () => {
|
49
|
+
const transmission = new Transmission({ baseUrl });
|
50
|
+
const contents = Buffer.from(fs.readFileSync(torrentFile)).toString('base64');
|
51
|
+
const res = await transmission.addTorrent(contents);
|
52
|
+
expect(res.result).toBe('success');
|
53
|
+
});
|
54
|
+
it('should get torrents', async () => {
|
55
|
+
const transmission = new Transmission({ baseUrl });
|
56
|
+
await setupTorrent(transmission);
|
57
|
+
const res = await transmission.listTorrents(undefined, ['id']);
|
58
|
+
expect(res.arguments.torrents).toHaveLength(1);
|
59
|
+
});
|
60
|
+
it('should get normalized all torrent data', async () => {
|
61
|
+
const transmission = new Transmission({ baseUrl });
|
62
|
+
await setupTorrent(transmission);
|
63
|
+
const res = await transmission.getAllData();
|
64
|
+
expect(res.torrents).toHaveLength(1);
|
65
|
+
expect(res.torrents[0].name).toBe(torrentName);
|
66
|
+
});
|
67
|
+
it('should get normalized torrent data', async () => {
|
68
|
+
const transmission = new Transmission({ baseUrl });
|
69
|
+
const id = await setupTorrent(transmission);
|
70
|
+
const res = await transmission.getTorrent(id);
|
71
|
+
expect(res.name).toBe(torrentName);
|
72
|
+
});
|
73
|
+
it('should remove torrent', async () => {
|
74
|
+
const transmission = new Transmission({ baseUrl });
|
75
|
+
const key = await setupTorrent(transmission);
|
76
|
+
await transmission.removeTorrent(key, false);
|
77
|
+
});
|
78
|
+
it('should verify torrent', async () => {
|
79
|
+
const transmission = new Transmission({ baseUrl });
|
80
|
+
const key = await setupTorrent(transmission);
|
81
|
+
await transmission.verifyTorrent(key);
|
82
|
+
});
|
83
|
+
it('should move in queue', async () => {
|
84
|
+
const transmission = new Transmission({ baseUrl });
|
85
|
+
const key = await setupTorrent(transmission);
|
86
|
+
await transmission.queueUp(key);
|
87
|
+
await transmission.queueDown(key);
|
88
|
+
await transmission.queueTop(key);
|
89
|
+
await transmission.queueBottom(key);
|
90
|
+
});
|
91
|
+
it('should report free space', async () => {
|
92
|
+
const transmission = new Transmission({ baseUrl });
|
93
|
+
const p = '/downloads';
|
94
|
+
const res = await transmission.freeSpace(p);
|
95
|
+
expect(res.result).toBe('success');
|
96
|
+
expect(res.arguments.path).toBe(p);
|
97
|
+
expect(typeof res.arguments['size-bytes']).toBe('number');
|
98
|
+
});
|
99
|
+
it('should add from url', async () => {
|
100
|
+
const transmission = new Transmission({ baseUrl });
|
101
|
+
const res = await transmission.addUrl('https://releases.ubuntu.com/20.10/ubuntu-20.10-desktop-amd64.iso.torrent');
|
102
|
+
expect(res.result).toBe('success');
|
103
|
+
});
|
104
|
+
it('should add torrent with normalized response', async () => {
|
105
|
+
const client = new Transmission({ baseUrl });
|
106
|
+
const torrent = await client.normalizedAddTorrent(fs.readFileSync(torrentFile), {
|
107
|
+
label: 'test',
|
108
|
+
});
|
109
|
+
expect(torrent.connectedPeers).toBe(0);
|
110
|
+
expect(torrent.connectedSeeds).toBe(0);
|
111
|
+
expect(torrent.downloadSpeed).toBe(0);
|
112
|
+
expect(torrent.eta).toBe(-1);
|
113
|
+
expect(torrent.isCompleted).toBe(false);
|
114
|
+
expect(torrent.label).toBe('test');
|
115
|
+
expect(torrent.name).toBe(torrentName);
|
116
|
+
expect(torrent.progress).toBeGreaterThanOrEqual(0);
|
117
|
+
expect(torrent.queuePosition).toBe(0);
|
118
|
+
// expect(torrent.ratio).toBe(0);
|
119
|
+
expect(torrent.savePath).toBe('/downloads');
|
120
|
+
expect(torrent.state).toBe(TorrentState.checking);
|
121
|
+
expect(torrent.stateMessage).toBe('');
|
122
|
+
expect(torrent.totalDownloaded).toBe(0);
|
123
|
+
expect(torrent.totalPeers).toBe(0);
|
124
|
+
expect(torrent.totalSeeds).toBe(0);
|
125
|
+
expect(torrent.totalSelected).toBe(1953349632);
|
126
|
+
// expect(torrent.totalSize).toBe(undefined);
|
127
|
+
expect(torrent.totalUploaded).toBe(0);
|
128
|
+
expect(torrent.uploadSpeed).toBe(0);
|
129
|
+
});
|
130
|
+
});
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ctrl/transmission",
|
3
|
-
"version": "
|
3
|
+
"version": "4.0.0",
|
4
4
|
"description": "TypeScript api wrapper for transmission using got",
|
5
5
|
"author": "Scott Cooper <scttcper@gmail.com>",
|
6
6
|
"license": "MIT",
|
@@ -9,8 +9,9 @@
|
|
9
9
|
"transmission",
|
10
10
|
"typescript"
|
11
11
|
],
|
12
|
-
"
|
13
|
-
"
|
12
|
+
"type": "module",
|
13
|
+
"main": "./dist/src/index.js",
|
14
|
+
"typings": "./dist/src/index.d.ts",
|
14
15
|
"files": [
|
15
16
|
"dist"
|
16
17
|
],
|
@@ -19,49 +20,40 @@
|
|
19
20
|
"lint": "eslint --ext .ts .",
|
20
21
|
"lint:fix": "eslint --fix --ext .ts .",
|
21
22
|
"prepare": "npm run build",
|
22
|
-
"build": "tsc
|
23
|
+
"build": "tsc",
|
23
24
|
"build:docs": "typedoc",
|
24
|
-
"test": "
|
25
|
-
"test:watch": "
|
26
|
-
"test:ci": "
|
25
|
+
"test": "vitest run",
|
26
|
+
"test:watch": "vitest",
|
27
|
+
"test:ci": "vitest run --coverage"
|
27
28
|
},
|
28
29
|
"dependencies": {
|
29
|
-
"@ctrl/shared-torrent": "^
|
30
|
-
"
|
31
|
-
"
|
30
|
+
"@ctrl/shared-torrent": "^4.1.0",
|
31
|
+
"@ctrl/url-join": "^2.0.0",
|
32
|
+
"got": "^12.1.0"
|
32
33
|
},
|
33
34
|
"devDependencies": {
|
34
|
-
"@
|
35
|
-
"@
|
36
|
-
"@
|
37
|
-
"
|
38
|
-
"
|
39
|
-
"
|
40
|
-
"
|
41
|
-
"
|
42
|
-
"p-wait-for": "3.2.0",
|
43
|
-
"typedoc": "0.22.10",
|
44
|
-
"typescript": "4.5.2"
|
35
|
+
"@ctrl/eslint-config": "3.4.4",
|
36
|
+
"@sindresorhus/tsconfig": "3.0.1",
|
37
|
+
"@types/node": "17.0.38",
|
38
|
+
"c8": "7.11.3",
|
39
|
+
"p-wait-for": "4.1.0",
|
40
|
+
"typedoc": "0.22.17",
|
41
|
+
"typescript": "4.7.2",
|
42
|
+
"vitest": "0.13.1"
|
45
43
|
},
|
46
44
|
"jest": {
|
47
45
|
"testEnvironment": "node",
|
48
46
|
"coverageProvider": "v8"
|
49
47
|
},
|
50
|
-
"babel": {
|
51
|
-
"presets": [
|
52
|
-
"@babel/preset-typescript"
|
53
|
-
],
|
54
|
-
"plugins": [
|
55
|
-
"@babel/plugin-transform-modules-commonjs"
|
56
|
-
]
|
57
|
-
},
|
58
48
|
"publishConfig": {
|
59
49
|
"access": "public"
|
60
50
|
},
|
61
51
|
"release": {
|
62
|
-
"
|
52
|
+
"branches": [
|
53
|
+
"master"
|
54
|
+
]
|
63
55
|
},
|
64
56
|
"engines": {
|
65
|
-
"node": ">=
|
57
|
+
"node": ">=14.16"
|
66
58
|
}
|
67
59
|
}
|
package/dist/index.d.ts
DELETED
package/dist/index.js
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
-
if (k2 === undefined) k2 = k;
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5
|
-
}) : (function(o, m, k, k2) {
|
6
|
-
if (k2 === undefined) k2 = k;
|
7
|
-
o[k2] = m[k];
|
8
|
-
}));
|
9
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
10
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
11
|
-
};
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
13
|
-
__exportStar(require("./transmission"), exports);
|
14
|
-
__exportStar(require("./types"), exports);
|
package/dist/types.js
DELETED