@ctrl/deluge 3.4.0 → 4.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.
@@ -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, AddTorrentResponse } from './types';
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
- "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.Deluge = void 0;
7
- const fs_1 = require("fs");
8
- const form_data_1 = __importDefault(require("form-data"));
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._msgId = 0;
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 ((_a = check === null || check === void 0 ? void 0 : check.body) === null || _a === void 0 ? void 0 : _a.result) {
104
+ if (check?.body?.result) {
93
105
  return true;
94
106
  }
95
107
  }
96
- catch (_b) {
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 = tough_cookie_1.Cookie.parse(res.headers['set-cookie'][0]);
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 form_data_1.default();
167
+ const form = new FormData();
168
+ const type = { type: 'application/x-bittorrent' };
156
169
  if (typeof torrent === 'string') {
157
- if (fs_1.existsSync(torrent)) {
158
- form.append('file', Buffer.from(fs_1.readFileSync(torrent)), 'temp.torrent');
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.append('file', Buffer.from(torrent, 'base64'), 'temp.torrent');
175
+ form.set('file', new File([Buffer.from(torrent, 'base64')], 'file.torrent', type));
162
176
  }
163
177
  }
164
178
  else {
165
- form.append('file', torrent, 'temp.torrent');
179
+ const file = new File([torrent], 'torrent', type);
180
+ form.set('file', file);
166
181
  }
167
- const url = url_join_1.urlJoin(this.config.baseUrl, '/upload');
168
- const res = await got_1.default.post(url, {
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);
@@ -190,11 +204,18 @@ class Deluge {
190
204
  return res.body.result;
191
205
  }
192
206
  async addTorrent(torrent, config = {}) {
193
- const upload = await this.upload(torrent);
194
- if (!upload.success || !upload.files.length) {
195
- throw new Error('Failed to upload');
207
+ let path;
208
+ if (Buffer.isBuffer(torrent) || !torrent.startsWith('/tmp/')) {
209
+ const upload = await this.upload(torrent);
210
+ if (!upload.success || !upload.files.length) {
211
+ throw new Error('Failed to upload');
212
+ }
213
+ path = upload.files[0];
214
+ }
215
+ else {
216
+ /** Assume paths starting with /tmp/ are from {@link Deluge.addTorrent} */
217
+ path = torrent;
196
218
  }
197
- const path = upload.files[0];
198
219
  const options = {
199
220
  file_priorities: [],
200
221
  add_paused: false,
@@ -225,11 +246,21 @@ class Deluge {
225
246
  if (options.startPaused) {
226
247
  torrentOptions.add_paused = true;
227
248
  }
228
- if (!Buffer.isBuffer(torrent)) {
229
- torrent = Buffer.from(torrent);
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];
230
263
  }
231
- const res = await this.addTorrent(torrent, torrentOptions);
232
- const torrentHash = res.result[0][1];
233
264
  if (options.label) {
234
265
  // sets the label but it might not set the label right away
235
266
  // sometimes takes a few seconds for label to reflect in results
@@ -279,7 +310,7 @@ class Deluge {
279
310
  }
280
311
  // update current password to new password
281
312
  this.config.password = password;
282
- this._cookie = tough_cookie_1.Cookie.parse(res.headers['set-cookie'][0]);
313
+ this._cookie = Cookie.parse(res.headers['set-cookie'][0]);
283
314
  return res.body;
284
315
  }
285
316
  async getAllData() {
@@ -492,7 +523,6 @@ class Deluge {
492
523
  }
493
524
  // eslint-disable-next-line @typescript-eslint/ban-types
494
525
  async request(method, params = [], needsAuth = true, autoConnect = true) {
495
- var _a, _b, _c, _d;
496
526
  if (this._msgId === 4096) {
497
527
  this._msgId = 0;
498
528
  }
@@ -506,23 +536,23 @@ class Deluge {
506
536
  }
507
537
  }
508
538
  const headers = {
509
- Cookie: (_b = (_a = this._cookie) === null || _a === void 0 ? void 0 : _a.cookieString) === null || _b === void 0 ? void 0 : _b.call(_a),
539
+ Cookie: this._cookie?.cookieString?.(),
510
540
  };
511
- const url = url_join_1.urlJoin(this.config.baseUrl, this.config.path);
512
- const res = await got_1.default.post(url, {
541
+ const url = urlJoin(this.config.baseUrl, this.config.path);
542
+ const res = await got.post(url, {
513
543
  json: {
514
544
  method,
515
545
  params,
516
546
  id: this._msgId++,
517
547
  },
518
548
  headers,
519
- retry: 0,
520
- // allow proxy agent
521
- agent: this.config.agent,
522
- timeout: this.config.timeout,
549
+ retry: { limit: 0 },
550
+ timeout: { request: this.config.timeout },
523
551
  responseType: 'json',
552
+ // allow proxy agent
553
+ ...(this.config.agent ? { agent: this.config.agent } : {}),
524
554
  });
525
- const err = (_d = (_c = res.body) === null || _c === void 0 ? void 0 : _c.error) !== null && _d !== void 0 ? _d : (typeof res.body === 'string' && res.body);
555
+ const err = res.body?.error ?? (typeof res.body === 'string' && res.body);
526
556
  if (err) {
527
557
  throw new Error(err.message || err);
528
558
  }
@@ -531,9 +561,9 @@ class Deluge {
531
561
  _normalizeTorrentData(id, torrent) {
532
562
  const dateAdded = new Date(torrent.time_added * 1000).toISOString();
533
563
  // normalize state to enum
534
- let state = shared_torrent_1.TorrentState.unknown;
535
- if (Object.keys(shared_torrent_1.TorrentState).includes(torrent.state.toLowerCase())) {
536
- state = shared_torrent_1.TorrentState[torrent.state.toLowerCase()];
564
+ let state = TorrentState.unknown;
565
+ if (Object.keys(TorrentState).includes(torrent.state.toLowerCase())) {
566
+ state = TorrentState[torrent.state.toLowerCase()];
537
567
  }
538
568
  const isCompleted = torrent.progress >= 100;
539
569
  const result = {
@@ -573,4 +603,3 @@ class Deluge {
573
603
  }
574
604
  }
575
605
  }
576
- exports.Deluge = Deluge;
@@ -0,0 +1,2 @@
1
+ export * from './deluge.js';
2
+ export * from './types.js';
@@ -0,0 +1,2 @@
1
+ export * from './deluge.js';
2
+ export * from './types.js';
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.4.0",
3
+ "version": "4.0.1",
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
- "main": "dist/index.js",
14
- "types": "dist/index.d.ts",
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 -p tsconfig.build.json",
24
+ "build": "tsc",
24
25
  "build:docs": "typedoc",
25
- "test": "jest --runInBand",
26
- "test:watch": "jest --watch --runInBand",
27
- "test:ci": "jest --runInBand --coverage --no-cache"
26
+ "test": "vitest run",
27
+ "test:watch": "vitest",
28
+ "test:ci": "vitest run --coverage"
28
29
  },
29
30
  "dependencies": {
30
- "@ctrl/shared-torrent": "^3.0.4",
31
- "@ctrl/url-join": "^1.0.4",
32
- "form-data": "^4.0.0",
33
- "got": "^11.8.2",
31
+ "@ctrl/magnet-link": "^3.1.0",
32
+ "@ctrl/shared-torrent": "^4.1.0",
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
- "@babel/plugin-transform-modules-commonjs": "7.13.8",
38
- "@babel/preset-typescript": "7.13.0",
39
- "@ctrl/eslint-config": "1.3.4",
40
- "@jest/globals": "26.6.2",
41
- "@types/node": "14.14.41",
42
- "@types/tough-cookie": "4.0.0",
43
- "jest": "26.6.3",
44
- "p-wait-for": "3.2.0",
45
- "typedoc": "0.20.35",
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.38",
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.2",
47
+ "vitest": "0.13.1"
58
48
  },
59
49
  "publishConfig": {
60
50
  "access": "public"
61
51
  },
62
52
  "release": {
63
- "branch": "master"
53
+ "branches": [
54
+ "master"
55
+ ]
64
56
  },
65
57
  "engines": {
66
- "node": ">=10.19.0"
58
+ "node": ">=14.16"
67
59
  }
68
60
  }
package/dist/types.js DELETED
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });