tor-dl 1.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.
Files changed (145) hide show
  1. package/AGENTS.md +53 -0
  2. package/README.md +255 -0
  3. package/bin/tordl.js +5 -0
  4. package/dist/bin/tordl.js +5 -0
  5. package/dist/bin/torrent-cli.js +5 -0
  6. package/dist/cli/display.d.ts +7 -0
  7. package/dist/cli/display.d.ts.map +1 -0
  8. package/dist/cli/display.js +58 -0
  9. package/dist/cli/display.js.map +1 -0
  10. package/dist/cli/parser.d.ts +5 -0
  11. package/dist/cli/parser.d.ts.map +1 -0
  12. package/dist/cli/parser.js +122 -0
  13. package/dist/cli/parser.js.map +1 -0
  14. package/dist/cli/progress.d.ts +15 -0
  15. package/dist/cli/progress.d.ts.map +1 -0
  16. package/dist/cli/progress.js +76 -0
  17. package/dist/cli/progress.js.map +1 -0
  18. package/dist/commands/download.d.ts +2 -0
  19. package/dist/commands/download.d.ts.map +1 -0
  20. package/dist/commands/download.js +70 -0
  21. package/dist/commands/download.js.map +1 -0
  22. package/dist/commands/search.d.ts +3 -0
  23. package/dist/commands/search.d.ts.map +1 -0
  24. package/dist/commands/search.js +46 -0
  25. package/dist/commands/search.js.map +1 -0
  26. package/dist/commands/update.d.ts +2 -0
  27. package/dist/commands/update.d.ts.map +1 -0
  28. package/dist/commands/update.js +32 -0
  29. package/dist/commands/update.js.map +1 -0
  30. package/dist/download/engine.d.ts +6 -0
  31. package/dist/download/engine.d.ts.map +1 -0
  32. package/dist/download/engine.js +163 -0
  33. package/dist/download/engine.js.map +1 -0
  34. package/dist/filters/category.d.ts +3 -0
  35. package/dist/filters/category.d.ts.map +1 -0
  36. package/dist/filters/category.js +24 -0
  37. package/dist/filters/category.js.map +1 -0
  38. package/dist/filters/index.d.ts +5 -0
  39. package/dist/filters/index.d.ts.map +1 -0
  40. package/dist/filters/index.js +13 -0
  41. package/dist/filters/index.js.map +1 -0
  42. package/dist/filters/seeds.d.ts +3 -0
  43. package/dist/filters/seeds.d.ts.map +1 -0
  44. package/dist/filters/seeds.js +7 -0
  45. package/dist/filters/seeds.js.map +1 -0
  46. package/dist/filters/size.d.ts +4 -0
  47. package/dist/filters/size.d.ts.map +1 -0
  48. package/dist/filters/size.js +36 -0
  49. package/dist/filters/size.js.map +1 -0
  50. package/dist/filters/sort.d.ts +5 -0
  51. package/dist/filters/sort.d.ts.map +1 -0
  52. package/dist/filters/sort.js +25 -0
  53. package/dist/filters/sort.js.map +1 -0
  54. package/dist/index.d.ts +11 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +30 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/sources/1337x.d.ts +11 -0
  59. package/dist/sources/1337x.d.ts.map +1 -0
  60. package/dist/sources/1337x.js +121 -0
  61. package/dist/sources/1337x.js.map +1 -0
  62. package/dist/sources/eztv.d.ts +11 -0
  63. package/dist/sources/eztv.d.ts.map +1 -0
  64. package/dist/sources/eztv.js +104 -0
  65. package/dist/sources/eztv.js.map +1 -0
  66. package/dist/sources/httpClient.d.ts +24 -0
  67. package/dist/sources/httpClient.d.ts.map +1 -0
  68. package/dist/sources/httpClient.js +42 -0
  69. package/dist/sources/httpClient.js.map +1 -0
  70. package/dist/sources/limetorrent.d.ts +11 -0
  71. package/dist/sources/limetorrent.d.ts.map +1 -0
  72. package/dist/sources/limetorrent.js +113 -0
  73. package/dist/sources/limetorrent.js.map +1 -0
  74. package/dist/sources/nyaa.d.ts +11 -0
  75. package/dist/sources/nyaa.d.ts.map +1 -0
  76. package/dist/sources/nyaa.js +119 -0
  77. package/dist/sources/nyaa.js.map +1 -0
  78. package/dist/sources/rarbg.d.ts +11 -0
  79. package/dist/sources/rarbg.d.ts.map +1 -0
  80. package/dist/sources/rarbg.js +122 -0
  81. package/dist/sources/rarbg.js.map +1 -0
  82. package/dist/sources/registry.d.ts +9 -0
  83. package/dist/sources/registry.d.ts.map +1 -0
  84. package/dist/sources/registry.js +70 -0
  85. package/dist/sources/registry.js.map +1 -0
  86. package/dist/sources/solidtorrents.d.ts +11 -0
  87. package/dist/sources/solidtorrents.d.ts.map +1 -0
  88. package/dist/sources/solidtorrents.js +105 -0
  89. package/dist/sources/solidtorrents.js.map +1 -0
  90. package/dist/sources/thepiratebay.d.ts +11 -0
  91. package/dist/sources/thepiratebay.d.ts.map +1 -0
  92. package/dist/sources/thepiratebay.js +67 -0
  93. package/dist/sources/thepiratebay.js.map +1 -0
  94. package/dist/sources/torlock.d.ts +11 -0
  95. package/dist/sources/torlock.d.ts.map +1 -0
  96. package/dist/sources/torlock.js +116 -0
  97. package/dist/sources/torlock.js.map +1 -0
  98. package/dist/sources/torrentproject.d.ts +11 -0
  99. package/dist/sources/torrentproject.d.ts.map +1 -0
  100. package/dist/sources/torrentproject.js +105 -0
  101. package/dist/sources/torrentproject.js.map +1 -0
  102. package/dist/sources/torrentscsv.d.ts +11 -0
  103. package/dist/sources/torrentscsv.d.ts.map +1 -0
  104. package/dist/sources/torrentscsv.js +62 -0
  105. package/dist/sources/torrentscsv.js.map +1 -0
  106. package/dist/sources/yts.d.ts +12 -0
  107. package/dist/sources/yts.d.ts.map +1 -0
  108. package/dist/sources/yts.js +88 -0
  109. package/dist/sources/yts.js.map +1 -0
  110. package/dist/types.d.ts +60 -0
  111. package/dist/types.d.ts.map +1 -0
  112. package/dist/types.js +3 -0
  113. package/dist/types.js.map +1 -0
  114. package/filters.json +9 -0
  115. package/package.json +37 -0
  116. package/sources.json +105 -0
  117. package/src/cli/display.ts +58 -0
  118. package/src/cli/parser.ts +96 -0
  119. package/src/cli/progress.ts +78 -0
  120. package/src/commands/download.ts +36 -0
  121. package/src/commands/search.ts +53 -0
  122. package/src/commands/update.ts +30 -0
  123. package/src/download/engine.ts +177 -0
  124. package/src/filters/category.ts +26 -0
  125. package/src/filters/index.ts +4 -0
  126. package/src/filters/seeds.ts +5 -0
  127. package/src/filters/size.ts +42 -0
  128. package/src/filters/sort.ts +34 -0
  129. package/src/index.ts +10 -0
  130. package/src/sources/1337x.ts +85 -0
  131. package/src/sources/eztv.ts +70 -0
  132. package/src/sources/httpClient.ts +39 -0
  133. package/src/sources/limetorrent.ts +78 -0
  134. package/src/sources/nyaa.ts +85 -0
  135. package/src/sources/rarbg.ts +86 -0
  136. package/src/sources/registry.ts +70 -0
  137. package/src/sources/solidtorrents.ts +70 -0
  138. package/src/sources/thepiratebay.ts +65 -0
  139. package/src/sources/torlock.ts +82 -0
  140. package/src/sources/torrentproject.ts +70 -0
  141. package/src/sources/torrentscsv.ts +58 -0
  142. package/src/sources/yts.ts +85 -0
  143. package/src/types.d.ts +86 -0
  144. package/src/types.ts +65 -0
  145. package/tsconfig.json +20 -0
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.downloadCommand = downloadCommand;
40
+ const display_1 = require("../cli/display");
41
+ const engine_1 = require("../download/engine");
42
+ const ora_1 = __importDefault(require("ora"));
43
+ async function downloadCommand(number, savePath) {
44
+ const results = (0, engine_1.getCachedResults)();
45
+ if (results.length === 0) {
46
+ (0, display_1.displayError)('No search results found. Run "tordl search <query>" first.');
47
+ process.exit(1);
48
+ }
49
+ if (number < 1 || number > results.length) {
50
+ (0, display_1.displayError)(`Invalid selection. Choose a number between 1 and ${results.length}.`);
51
+ process.exit(1);
52
+ }
53
+ const result = results[number - 1];
54
+ (0, display_1.displayInfo)(`Downloading: ${result.name}`);
55
+ (0, display_1.displayInfo)(`Source: ${result.source}`);
56
+ (0, display_1.displayInfo)(`Size: ${result.size}`);
57
+ (0, display_1.displayInfo)(`Seeds: ${result.seeds}\n`);
58
+ const spinner = (0, ora_1.default)('Starting download...').start();
59
+ try {
60
+ const { downloadTorrent } = await Promise.resolve().then(() => __importStar(require('../download/engine')));
61
+ await downloadTorrent(result, { savePath });
62
+ spinner.succeed('Download complete!');
63
+ }
64
+ catch (error) {
65
+ spinner.fail(`Download failed: ${error.message}`);
66
+ (0, display_1.displayError)('Make sure you have a stable internet connection and sufficient disk space.');
67
+ process.exit(1);
68
+ }
69
+ }
70
+ //# sourceMappingURL=download.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/commands/download.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,0CA+BC;AAnCD,4CAA2E;AAC3E,+CAAsD;AACtD,8CAAsB;AAEf,KAAK,UAAU,eAAe,CAAC,MAAc,EAAE,QAAiB;IACrE,MAAM,OAAO,GAAG,IAAA,yBAAgB,GAAE,CAAC;IAEnC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,IAAA,sBAAY,EAAC,4DAA4D,CAAC,CAAC;QAC3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,GAAG,CAAC,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1C,IAAA,sBAAY,EAAC,oDAAoD,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEnC,IAAA,qBAAW,EAAC,gBAAgB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,IAAA,qBAAW,EAAC,WAAW,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,IAAA,qBAAW,EAAC,SAAS,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACpC,IAAA,qBAAW,EAAC,UAAU,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;IAExC,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,sBAAsB,CAAC,CAAC,KAAK,EAAE,CAAC;IAEpD,IAAI,CAAC;QACH,MAAM,EAAE,eAAe,EAAE,GAAG,wDAAa,oBAAoB,GAAC,CAAC;QAC/D,MAAM,eAAe,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,oBAAoB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAClD,IAAA,sBAAY,EAAC,4EAA4E,CAAC,CAAC;QAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { SearchOptions } from '../types';
2
+ export declare function searchCommand(options: SearchOptions): Promise<void>;
3
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAiB,MAAM,UAAU,CAAC;AAMxD,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA6CzE"}
@@ -0,0 +1,46 @@
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.searchCommand = searchCommand;
7
+ const ora_1 = __importDefault(require("ora"));
8
+ const registry_1 = require("../sources/registry");
9
+ const filters_1 = require("../filters");
10
+ const display_1 = require("../cli/display");
11
+ const engine_1 = require("../download/engine");
12
+ async function searchCommand(options) {
13
+ const spinner = (0, ora_1.default)('Searching torrent sources...').start();
14
+ let sources = (0, registry_1.getEnabledSources)();
15
+ if (options.sources && options.sources.length > 0) {
16
+ const requested = options.sources.map(s => s.toLowerCase());
17
+ sources = sources.filter(s => requested.includes(s.name.toLowerCase()));
18
+ }
19
+ const allResults = [];
20
+ for (const source of sources) {
21
+ try {
22
+ spinner.text = `Searching ${source.name}...`;
23
+ const results = await source.search(options.query, options.category);
24
+ allResults.push(...results);
25
+ }
26
+ catch (error) {
27
+ spinner.warn(`Failed to search ${source.name}`);
28
+ }
29
+ }
30
+ spinner.succeed(`Search complete. Found ${allResults.length} results.`);
31
+ let filtered = (0, filters_1.filterByCategory)(allResults, options.category || 'all');
32
+ if (options.minSeeds && options.minSeeds > 0) {
33
+ filtered = (0, filters_1.filterBySeeds)(filtered, options.minSeeds);
34
+ }
35
+ if (options.minSize || options.maxSize) {
36
+ filtered = (0, filters_1.filterBySize)(filtered, options.minSize, options.maxSize);
37
+ }
38
+ filtered = (0, filters_1.sortResults)(filtered, options.sortBy || 'seeds', options.order || 'desc');
39
+ if (options.limit && options.limit > 0) {
40
+ filtered = filtered.slice(0, options.limit);
41
+ }
42
+ filtered = filtered.map((r, i) => ({ ...r, num: i + 1 }));
43
+ (0, engine_1.cacheResults)(filtered);
44
+ (0, display_1.displayResults)(filtered);
45
+ }
46
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":";;;;;AAOA,sCA6CC;AApDD,8CAAsB;AAEtB,kDAAwD;AACxD,wCAAwF;AACxF,4CAA8D;AAC9D,+CAAkD;AAE3C,KAAK,UAAU,aAAa,CAAC,OAAsB;IACxD,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,8BAA8B,CAAC,CAAC,KAAK,EAAE,CAAC;IAE5D,IAAI,OAAO,GAAG,IAAA,4BAAiB,GAAE,CAAC;IAElC,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5D,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,UAAU,GAAoB,EAAE,CAAC;IAEvC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,GAAG,aAAa,MAAM,CAAC,IAAI,KAAK,CAAC;YAC7C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;YACrE,UAAU,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,oBAAoB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,OAAO,CAAC,0BAA0B,UAAU,CAAC,MAAM,WAAW,CAAC,CAAC;IAExE,IAAI,QAAQ,GAAG,IAAA,0BAAgB,EAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC;IAEvE,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC7C,QAAQ,GAAG,IAAA,uBAAa,EAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACvC,QAAQ,GAAG,IAAA,sBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACtE,CAAC;IAED,QAAQ,GAAG,IAAA,qBAAW,EAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC;IAErF,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QACvC,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IAED,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAE1D,IAAA,qBAAY,EAAC,QAAQ,CAAC,CAAC;IAEvB,IAAA,wBAAc,EAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function updateCommand(): Promise<void>;
2
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAMA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAuBnD"}
@@ -0,0 +1,32 @@
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.updateCommand = updateCommand;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const fs_1 = require("fs");
9
+ const path_1 = require("path");
10
+ const display_1 = require("../cli/display");
11
+ const registry_1 = require("../sources/registry");
12
+ async function updateCommand() {
13
+ const updateUrl = (0, registry_1.getUpdateUrl)();
14
+ if (!updateUrl) {
15
+ (0, display_1.displayError)('No update URL configured. Update sources.json with an updateUrl first.');
16
+ return;
17
+ }
18
+ (0, display_1.displayInfo)(`Fetching latest sources from: ${updateUrl}`);
19
+ try {
20
+ const { data } = await axios_1.default.get(updateUrl, { timeout: 15000 });
21
+ const localPath = (0, path_1.join)(process.cwd(), 'sources.json');
22
+ (0, fs_1.writeFileSync)(localPath, JSON.stringify(data, null, 2));
23
+ (0, display_1.displaySuccess)('Sources updated successfully!');
24
+ (0, display_1.displayInfo)(`Updated to version: ${data.version || 'unknown'}`);
25
+ (0, display_1.displayInfo)(`Sources: ${Object.keys(data.sources || {}).join(', ')}`);
26
+ }
27
+ catch (error) {
28
+ (0, display_1.displayError)(`Failed to update sources: ${error.message}`);
29
+ (0, display_1.displayInfo)('Check your internet connection and the update URL.');
30
+ }
31
+ }
32
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":";;;;;AAMA,sCAuBC;AA7BD,kDAA0B;AAC1B,2BAA+C;AAC/C,+BAA4B;AAC5B,4CAA2E;AAC3E,kDAAmD;AAE5C,KAAK,UAAU,aAAa;IACjC,MAAM,SAAS,GAAG,IAAA,uBAAY,GAAE,CAAC;IAEjC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,IAAA,sBAAY,EAAC,wEAAwE,CAAC,CAAC;QACvF,OAAO;IACT,CAAC;IAED,IAAA,qBAAW,EAAC,iCAAiC,SAAS,EAAE,CAAC,CAAC;IAE1D,IAAI,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,eAAK,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAEhE,MAAM,SAAS,GAAG,IAAA,WAAI,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;QACtD,IAAA,kBAAa,EAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAExD,IAAA,wBAAc,EAAC,+BAA+B,CAAC,CAAC;QAChD,IAAA,qBAAW,EAAC,uBAAuB,IAAI,CAAC,OAAO,IAAI,SAAS,EAAE,CAAC,CAAC;QAChE,IAAA,qBAAW,EAAC,YAAY,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,IAAA,sBAAY,EAAC,6BAA6B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3D,IAAA,qBAAW,EAAC,oDAAoD,CAAC,CAAC;IACpE,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { TorrentResult, DownloadOptions } from '../types';
2
+ export declare function cacheResults(results: TorrentResult[]): void;
3
+ export declare function getCachedResults(): TorrentResult[];
4
+ export declare function downloadTorrent(result: TorrentResult, options?: DownloadOptions): Promise<void>;
5
+ export declare function downloadByNumber(number: number, savePath?: string): Promise<void>;
6
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/download/engine.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAwB1D,wBAAgB,YAAY,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI,CAG3D;AAED,wBAAgB,gBAAgB,IAAI,aAAa,EAAE,CAKlD;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,aAAa,EACrB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAgGf;AAuBD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAaf"}
@@ -0,0 +1,163 @@
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.cacheResults = cacheResults;
7
+ exports.getCachedResults = getCachedResults;
8
+ exports.downloadTorrent = downloadTorrent;
9
+ exports.downloadByNumber = downloadByNumber;
10
+ const webtorrent_1 = __importDefault(require("webtorrent"));
11
+ const progress_1 = require("../cli/progress");
12
+ const axios_1 = __importDefault(require("axios"));
13
+ const fs_1 = require("fs");
14
+ const path_1 = require("path");
15
+ const CACHE_FILE = (0, path_1.join)(process.cwd(), '.torrent-cache.json');
16
+ function saveCache(results) {
17
+ try {
18
+ (0, fs_1.writeFileSync)(CACHE_FILE, JSON.stringify(results, null, 2));
19
+ }
20
+ catch (e) { /* ignore */ }
21
+ }
22
+ function loadCache() {
23
+ try {
24
+ if ((0, fs_1.existsSync)(CACHE_FILE)) {
25
+ return JSON.parse((0, fs_1.readFileSync)(CACHE_FILE, 'utf-8'));
26
+ }
27
+ }
28
+ catch (e) { /* ignore */ }
29
+ return [];
30
+ }
31
+ let cachedResults = [];
32
+ function cacheResults(results) {
33
+ cachedResults = results;
34
+ saveCache(results);
35
+ }
36
+ function getCachedResults() {
37
+ if (cachedResults.length === 0) {
38
+ cachedResults = loadCache();
39
+ }
40
+ return cachedResults;
41
+ }
42
+ async function downloadTorrent(result, options = {}) {
43
+ const client = new webtorrent_1.default();
44
+ const progress = new progress_1.DownloadProgress();
45
+ const savePath = options.savePath || process.cwd();
46
+ let torrentId;
47
+ if (result.magnet && result.magnet.startsWith('magnet:')) {
48
+ torrentId = result.magnet;
49
+ }
50
+ else if (result.url && result.url.includes('magnet:')) {
51
+ torrentId = result.url;
52
+ }
53
+ else if (result.url && result.url.includes('nyaa.si')) {
54
+ console.log('Fetching magnet link from Nyaa...');
55
+ const magnet = await getMagnetFromResult(result);
56
+ if (magnet) {
57
+ torrentId = magnet;
58
+ }
59
+ else {
60
+ throw new Error('Could not get magnet link from Nyaa page');
61
+ }
62
+ }
63
+ else {
64
+ console.log('Fetching torrent file...');
65
+ const torrentUrl = await getTorrentUrl(result);
66
+ if (torrentUrl) {
67
+ const response = await axios_1.default.get(torrentUrl, { responseType: 'arraybuffer' });
68
+ const tempFile = (0, path_1.join)(savePath, 'temp.torrent');
69
+ (0, fs_1.writeFileSync)(tempFile, response.data);
70
+ torrentId = tempFile;
71
+ }
72
+ else {
73
+ throw new Error('Could not get torrent URL');
74
+ }
75
+ }
76
+ console.log(`\nDownloading: ${result.name}`);
77
+ console.log(`Saving to: ${savePath}\n`);
78
+ return new Promise((resolve, reject) => {
79
+ console.log('Adding torrent to client...');
80
+ console.log('Torrent ID:', torrentId.substring(0, 60) + '...');
81
+ const torrent = client.add(torrentId, {
82
+ path: savePath
83
+ });
84
+ torrent.on('warning', (warn) => {
85
+ console.log('Torrent warning:', warn.message);
86
+ });
87
+ torrent.on('peer', (peer) => {
88
+ console.log('New peer connected:', peer);
89
+ });
90
+ console.log('Torrent added, waiting for ready...');
91
+ torrent.on('ready', () => {
92
+ const total = torrent.length;
93
+ console.log(`✓ Torrent ready! Total size: ${(total / (1024 * 1024)).toFixed(2)} MB`);
94
+ console.log(` Files: ${torrent.files.map(f => f.name).join(', ')}`);
95
+ console.log(` Info hash: ${torrent.infoHash}`);
96
+ progress.start(total);
97
+ torrent.on('download', (bytes) => {
98
+ const percent = ((torrent.downloaded / total) * 100).toFixed(1);
99
+ process.stdout.write(`\rDownloading: ${percent}% (${(torrent.downloaded / 1024 / 1024).toFixed(1)} MB / ${(total / 1024 / 1024).toFixed(1)} MB) - ${torrent.peers.length} peers `);
100
+ progress.update(torrent.downloaded, total);
101
+ });
102
+ torrent.on('done', () => {
103
+ progress.stop();
104
+ console.log('\n\n✓ Download complete!');
105
+ console.log(`Downloaded to: ${savePath}`);
106
+ client.destroy();
107
+ resolve();
108
+ });
109
+ });
110
+ torrent.on('error', (err) => {
111
+ console.error('\nDownload error:', err.message);
112
+ client.destroy();
113
+ reject(err);
114
+ });
115
+ setTimeout(() => {
116
+ console.log('\n\nDebug:');
117
+ console.log(' Downloaded:', torrent.downloaded);
118
+ console.log(' Length:', torrent.length);
119
+ console.log(' Peers:', torrent.peers?.length || 0);
120
+ console.log(' Done:', torrent.done);
121
+ if (torrent.downloaded > 0) {
122
+ console.log('\nDownload in progress but taking long...');
123
+ console.log(`Progress: ${(torrent.downloaded / torrent.length * 100).toFixed(1)}%`);
124
+ }
125
+ else {
126
+ console.log('\nNo progress after 60s - may be stuck or no peers');
127
+ }
128
+ }, 60000);
129
+ });
130
+ }
131
+ async function getTorrentUrl(result) {
132
+ if (result.magnet && result.magnet.startsWith('magnet:')) {
133
+ return result.magnet;
134
+ }
135
+ return result.url;
136
+ }
137
+ async function getMagnetFromResult(result) {
138
+ if (result.magnet)
139
+ return result.magnet;
140
+ if (!result.url)
141
+ return '';
142
+ try {
143
+ const { data } = await axios_1.default.get(result.url, { timeout: 15000 });
144
+ const cheerio = require('cheerio');
145
+ const $ = cheerio.load(data);
146
+ return $('a[href^="magnet:"]').attr('href') || '';
147
+ }
148
+ catch {
149
+ return '';
150
+ }
151
+ }
152
+ async function downloadByNumber(number, savePath) {
153
+ const results = getCachedResults();
154
+ if (results.length === 0) {
155
+ throw new Error('No search results. Run "tordl search" first.');
156
+ }
157
+ if (number < 1 || number > results.length) {
158
+ throw new Error(`Invalid number. Choose between 1 and ${results.length}`);
159
+ }
160
+ const result = results[number - 1];
161
+ await downloadTorrent(result, { savePath });
162
+ }
163
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/download/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { TorrentResult } from '../types';
2
+ export declare function filterByCategory(results: TorrentResult[], category: string): TorrentResult[];
3
+ //# sourceMappingURL=category.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"category.d.ts","sourceRoot":"","sources":["../../src/filters/category.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE,CAuB5F"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.filterByCategory = filterByCategory;
4
+ function filterByCategory(results, category) {
5
+ if (!category || category === 'all') {
6
+ return results;
7
+ }
8
+ return results.filter(r => {
9
+ const name = r.name.toLowerCase();
10
+ const cat = category.toLowerCase();
11
+ if (cat === 'movie') {
12
+ return name.includes('movie') || name.includes('720p') || name.includes('1080p') ||
13
+ name.includes('2160p') || name.includes('bluray') || name.includes('brrip') ||
14
+ name.includes('webrip') || name.includes('web-dl') || name.includes('dvdrip');
15
+ }
16
+ if (cat === 'tv') {
17
+ return name.includes('s01') || name.includes('s02') || name.includes('episode') ||
18
+ name.includes('season') || name.includes('tv') || name.includes('hdtv') ||
19
+ name.includes('webrip') || name.includes('web-dl');
20
+ }
21
+ return true;
22
+ });
23
+ }
24
+ //# sourceMappingURL=category.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"category.js","sourceRoot":"","sources":["../../src/filters/category.ts"],"names":[],"mappings":";;AAEA,4CAuBC;AAvBD,SAAgB,gBAAgB,CAAC,OAAwB,EAAE,QAAgB;IACzE,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QACpC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;QACxB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QAEnC,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACzE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAC3E,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACvF,CAAC;QAED,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;gBACxE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;gBACvE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { filterByCategory } from './category';
2
+ export { filterBySize, parseSize } from './size';
3
+ export { filterBySeeds } from './seeds';
4
+ export { sortResults, SortField, SortOrder } from './sort';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/filters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sortResults = exports.filterBySeeds = exports.parseSize = exports.filterBySize = exports.filterByCategory = void 0;
4
+ var category_1 = require("./category");
5
+ Object.defineProperty(exports, "filterByCategory", { enumerable: true, get: function () { return category_1.filterByCategory; } });
6
+ var size_1 = require("./size");
7
+ Object.defineProperty(exports, "filterBySize", { enumerable: true, get: function () { return size_1.filterBySize; } });
8
+ Object.defineProperty(exports, "parseSize", { enumerable: true, get: function () { return size_1.parseSize; } });
9
+ var seeds_1 = require("./seeds");
10
+ Object.defineProperty(exports, "filterBySeeds", { enumerable: true, get: function () { return seeds_1.filterBySeeds; } });
11
+ var sort_1 = require("./sort");
12
+ Object.defineProperty(exports, "sortResults", { enumerable: true, get: function () { return sort_1.sortResults; } });
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/filters/index.ts"],"names":[],"mappings":";;;AAAA,uCAA8C;AAArC,4GAAA,gBAAgB,OAAA;AACzB,+BAAiD;AAAxC,oGAAA,YAAY,OAAA;AAAE,iGAAA,SAAS,OAAA;AAChC,iCAAwC;AAA/B,sGAAA,aAAa,OAAA;AACtB,+BAA2D;AAAlD,mGAAA,WAAW,OAAA"}
@@ -0,0 +1,3 @@
1
+ import { TorrentResult } from '../types';
2
+ export declare function filterBySeeds(results: TorrentResult[], minSeeds?: number): TorrentResult[];
3
+ //# sourceMappingURL=seeds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seeds.d.ts","sourceRoot":"","sources":["../../src/filters/seeds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,wBAAgB,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,QAAQ,GAAE,MAAU,GAAG,aAAa,EAAE,CAE7F"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.filterBySeeds = filterBySeeds;
4
+ function filterBySeeds(results, minSeeds = 0) {
5
+ return results.filter(r => r.seeds >= minSeeds);
6
+ }
7
+ //# sourceMappingURL=seeds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seeds.js","sourceRoot":"","sources":["../../src/filters/seeds.ts"],"names":[],"mappings":";;AAEA,sCAEC;AAFD,SAAgB,aAAa,CAAC,OAAwB,EAAE,WAAmB,CAAC;IAC1E,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { TorrentResult } from '../types';
2
+ export declare function parseSize(size: string): number;
3
+ export declare function filterBySize(results: TorrentResult[], minSize?: string, maxSize?: string): TorrentResult[];
4
+ //# sourceMappingURL=size.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"size.d.ts","sourceRoot":"","sources":["../../src/filters/size.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkB9C;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,aAAa,EAAE,EACxB,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,aAAa,EAAE,CAejB"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSize = parseSize;
4
+ exports.filterBySize = filterBySize;
5
+ function parseSize(size) {
6
+ if (!size || size === 'Unknown' || size === 'N/A')
7
+ return 0;
8
+ const match = size.toString().match(/([\d.]+)\s*(GB|MB|TB|KB|B)/i);
9
+ if (!match)
10
+ return 0;
11
+ const value = parseFloat(match[1]);
12
+ const unit = match[2].toUpperCase();
13
+ const multipliers = {
14
+ 'B': 1,
15
+ 'KB': 1024,
16
+ 'MB': 1024 ** 2,
17
+ 'GB': 1024 ** 3,
18
+ 'TB': 1024 ** 4
19
+ };
20
+ return value * (multipliers[unit] || 1);
21
+ }
22
+ function filterBySize(results, minSize, maxSize) {
23
+ if (!minSize && !maxSize) {
24
+ return results;
25
+ }
26
+ const minBytes = minSize ? parseSize(minSize) : 0;
27
+ const maxBytes = maxSize && maxSize !== '0' ? parseSize(maxSize) : Number.MAX_SAFE_INTEGER;
28
+ return results.filter(r => {
29
+ const sizeBytes = r.sizeBytes;
30
+ if (typeof sizeBytes !== 'number' || isNaN(sizeBytes)) {
31
+ return true;
32
+ }
33
+ return sizeBytes >= minBytes && sizeBytes <= maxBytes;
34
+ });
35
+ }
36
+ //# sourceMappingURL=size.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"size.js","sourceRoot":"","sources":["../../src/filters/size.ts"],"names":[],"mappings":";;AAEA,8BAkBC;AAED,oCAmBC;AAvCD,SAAgB,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,CAAC,CAAC;IAE5D,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACnE,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC;IAErB,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAEpC,MAAM,WAAW,GAA2B;QAC1C,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,IAAI,IAAI,CAAC;QACf,IAAI,EAAE,IAAI,IAAI,CAAC;QACf,IAAI,EAAE,IAAI,IAAI,CAAC;KAChB,CAAC;IAEF,OAAO,KAAK,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,SAAgB,YAAY,CAC1B,OAAwB,EACxB,OAAgB,EAChB,OAAgB;IAEhB,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,OAAO,IAAI,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC;IAE3F,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;QACxB,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;QAC9B,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YACtD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,SAAS,IAAI,QAAQ,IAAI,SAAS,IAAI,QAAQ,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { TorrentResult } from '../types';
2
+ export type SortField = 'seeds' | 'size' | 'date';
3
+ export type SortOrder = 'asc' | 'desc';
4
+ export declare function sortResults(results: TorrentResult[], sortBy?: SortField, order?: SortOrder): TorrentResult[];
5
+ //# sourceMappingURL=sort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sort.d.ts","sourceRoot":"","sources":["../../src/filters/sort.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAClD,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvC,wBAAgB,WAAW,CACzB,OAAO,EAAE,aAAa,EAAE,EACxB,MAAM,GAAE,SAAmB,EAC3B,KAAK,GAAE,SAAkB,GACxB,aAAa,EAAE,CAwBjB"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sortResults = sortResults;
4
+ function sortResults(results, sortBy = 'seeds', order = 'desc') {
5
+ const sorted = [...results];
6
+ sorted.sort((a, b) => {
7
+ let comparison = 0;
8
+ switch (sortBy) {
9
+ case 'seeds':
10
+ comparison = a.seeds - b.seeds;
11
+ break;
12
+ case 'size':
13
+ comparison = (a.sizeBytes || 0) - (b.sizeBytes || 0);
14
+ break;
15
+ case 'date':
16
+ comparison = (a.date || '').localeCompare(b.date || '');
17
+ break;
18
+ default:
19
+ comparison = a.seeds - b.seeds;
20
+ }
21
+ return order === 'desc' ? -comparison : comparison;
22
+ });
23
+ return sorted;
24
+ }
25
+ //# sourceMappingURL=sort.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sort.js","sourceRoot":"","sources":["../../src/filters/sort.ts"],"names":[],"mappings":";;AAKA,kCA4BC;AA5BD,SAAgB,WAAW,CACzB,OAAwB,EACxB,SAAoB,OAAO,EAC3B,QAAmB,MAAM;IAEzB,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IAE5B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACnB,IAAI,UAAU,GAAG,CAAC,CAAC;QAEnB,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,OAAO;gBACV,UAAU,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;gBAC/B,MAAM;YACR,KAAK,MAAM;gBACT,UAAU,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;gBACrD,MAAM;YACR,KAAK,MAAM;gBACT,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;gBACxD,MAAM;YACR;gBACE,UAAU,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;QACnC,CAAC;QAED,OAAO,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,11 @@
1
+ export * from './types';
2
+ export { createParser, loadFilters } from './cli/parser';
3
+ export * from './cli/display';
4
+ export * from './cli/progress';
5
+ export * from './sources/registry';
6
+ export * from './filters';
7
+ export * from './download/engine';
8
+ export * from './commands/search';
9
+ export * from './commands/download';
10
+ export * from './commands/update';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACzD,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.loadFilters = exports.createParser = void 0;
18
+ __exportStar(require("./types"), exports);
19
+ var parser_1 = require("./cli/parser");
20
+ Object.defineProperty(exports, "createParser", { enumerable: true, get: function () { return parser_1.createParser; } });
21
+ Object.defineProperty(exports, "loadFilters", { enumerable: true, get: function () { return parser_1.loadFilters; } });
22
+ __exportStar(require("./cli/display"), exports);
23
+ __exportStar(require("./cli/progress"), exports);
24
+ __exportStar(require("./sources/registry"), exports);
25
+ __exportStar(require("./filters"), exports);
26
+ __exportStar(require("./download/engine"), exports);
27
+ __exportStar(require("./commands/search"), exports);
28
+ __exportStar(require("./commands/download"), exports);
29
+ __exportStar(require("./commands/update"), exports);
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,uCAAyD;AAAhD,sGAAA,YAAY,OAAA;AAAE,qGAAA,WAAW,OAAA;AAClC,gDAA8B;AAC9B,iDAA+B;AAC/B,qDAAmC;AACnC,4CAA0B;AAC1B,oDAAkC;AAClC,oDAAkC;AAClC,sDAAoC;AACpC,oDAAkC"}
@@ -0,0 +1,11 @@
1
+ import { TorrentResult, SourceScraper } from '../types';
2
+ export declare class _1337xScraper implements SourceScraper {
3
+ name: string;
4
+ search(query: string, category?: string): Promise<TorrentResult[]>;
5
+ getTorrentUrl(result: TorrentResult): Promise<string>;
6
+ getMagnet(result: TorrentResult): Promise<string>;
7
+ private parseSize;
8
+ }
9
+ declare const _default: _1337xScraper;
10
+ export default _default;
11
+ //# sourceMappingURL=1337x.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1337x.d.ts","sourceRoot":"","sources":["../../src/sources/1337x.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGxD,qBAAa,aAAc,YAAW,aAAa;IACjD,IAAI,SAAW;IAET,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IA4ClE,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAWrD,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAUvD,OAAO,CAAC,SAAS;CASlB;;AAED,wBAAmC"}