cross-seed 7.0.0-1 → 7.0.0-10

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 (287) hide show
  1. package/dist/Result.d.ts +27 -0
  2. package/dist/Result.js +64 -0
  3. package/dist/Result.js.map +1 -0
  4. package/dist/action.d.ts +34 -0
  5. package/dist/action.js +694 -0
  6. package/dist/action.js.map +1 -0
  7. package/dist/arr.d.ts +31 -0
  8. package/dist/arr.js +267 -0
  9. package/dist/arr.js.map +1 -0
  10. package/dist/auth.d.ts +3 -0
  11. package/dist/auth.js +28 -0
  12. package/dist/auth.js.map +1 -0
  13. package/dist/clients/Deluge.d.ts +153 -0
  14. package/dist/clients/Deluge.js +699 -0
  15. package/dist/clients/Deluge.js.map +1 -0
  16. package/dist/clients/QBittorrent.d.ts +218 -0
  17. package/dist/clients/QBittorrent.js +786 -0
  18. package/dist/clients/QBittorrent.js.map +1 -0
  19. package/dist/clients/RTorrent.d.ts +43 -0
  20. package/dist/clients/RTorrent.js +658 -0
  21. package/dist/clients/RTorrent.js.map +1 -0
  22. package/dist/clients/TorrentClient.d.ts +108 -0
  23. package/dist/clients/TorrentClient.js +342 -0
  24. package/dist/clients/TorrentClient.js.map +1 -0
  25. package/dist/clients/Transmission.d.ts +43 -0
  26. package/dist/clients/Transmission.js +405 -0
  27. package/dist/clients/Transmission.js.map +1 -0
  28. package/dist/cmd.d.ts +2 -0
  29. package/dist/cmd.js +128 -0
  30. package/dist/cmd.js.map +1 -0
  31. package/dist/configSchema.d.ts +1 -0
  32. package/dist/configSchema.js +2 -0
  33. package/dist/configSchema.js.map +1 -0
  34. package/dist/configuration.d.ts +63 -0
  35. package/dist/configuration.js +321 -0
  36. package/dist/configuration.js.map +1 -0
  37. package/dist/constants.d.ts +108 -0
  38. package/dist/constants.js +251 -0
  39. package/dist/constants.js.map +1 -0
  40. package/dist/dataFiles.d.ts +8 -0
  41. package/dist/dataFiles.js +223 -0
  42. package/dist/dataFiles.js.map +1 -0
  43. package/dist/db.d.ts +14 -0
  44. package/dist/db.js +287 -0
  45. package/dist/db.js.map +1 -0
  46. package/dist/dbConfig.d.ts +4 -0
  47. package/dist/dbConfig.js +67 -0
  48. package/dist/dbConfig.js.map +1 -0
  49. package/dist/decide.d.ts +25 -0
  50. package/dist/decide.js +553 -0
  51. package/dist/decide.js.map +1 -0
  52. package/dist/diagnostics/db.d.ts +21 -0
  53. package/dist/diagnostics/db.js +107 -0
  54. package/dist/diagnostics/db.js.map +1 -0
  55. package/dist/diff.d.ts +1 -0
  56. package/dist/diff.js +24 -0
  57. package/dist/diff.js.map +1 -0
  58. package/dist/errors.d.ts +3 -0
  59. package/dist/errors.js +7 -0
  60. package/dist/errors.js.map +1 -0
  61. package/dist/indexers.d.ts +105 -0
  62. package/dist/indexers.js +248 -0
  63. package/dist/indexers.js.map +1 -0
  64. package/dist/inject.d.ts +2 -0
  65. package/dist/inject.js +594 -0
  66. package/dist/inject.js.map +1 -0
  67. package/dist/jobs.d.ts +29 -0
  68. package/dist/jobs.js +151 -0
  69. package/dist/jobs.js.map +1 -0
  70. package/dist/logger.d.ts +29 -0
  71. package/dist/logger.js +157 -0
  72. package/dist/logger.js.map +1 -0
  73. package/dist/migrations/00-initialSchema.d.ts +9 -0
  74. package/dist/migrations/00-initialSchema.js +30 -0
  75. package/dist/migrations/00-initialSchema.js.map +1 -0
  76. package/dist/migrations/01-jobs.d.ts +9 -0
  77. package/dist/migrations/01-jobs.js +12 -0
  78. package/dist/migrations/01-jobs.js.map +1 -0
  79. package/dist/migrations/02-timestamps.d.ts +9 -0
  80. package/dist/migrations/02-timestamps.js +21 -0
  81. package/dist/migrations/02-timestamps.js.map +1 -0
  82. package/dist/migrations/03-rateLimits.d.ts +9 -0
  83. package/dist/migrations/03-rateLimits.js +14 -0
  84. package/dist/migrations/03-rateLimits.js.map +1 -0
  85. package/dist/migrations/04-auth.d.ts +9 -0
  86. package/dist/migrations/04-auth.js +13 -0
  87. package/dist/migrations/04-auth.js.map +1 -0
  88. package/dist/migrations/05-caps.d.ts +9 -0
  89. package/dist/migrations/05-caps.js +16 -0
  90. package/dist/migrations/05-caps.js.map +1 -0
  91. package/dist/migrations/06-uniqueDecisions.d.ts +9 -0
  92. package/dist/migrations/06-uniqueDecisions.js +29 -0
  93. package/dist/migrations/06-uniqueDecisions.js.map +1 -0
  94. package/dist/migrations/07-limits.d.ts +9 -0
  95. package/dist/migrations/07-limits.js +12 -0
  96. package/dist/migrations/07-limits.js.map +1 -0
  97. package/dist/migrations/08-rss.d.ts +9 -0
  98. package/dist/migrations/08-rss.js +15 -0
  99. package/dist/migrations/08-rss.js.map +1 -0
  100. package/dist/migrations/09-clientAndDataSearchees.d.ts +9 -0
  101. package/dist/migrations/09-clientAndDataSearchees.js +34 -0
  102. package/dist/migrations/09-clientAndDataSearchees.js.map +1 -0
  103. package/dist/migrations/10-indexerNameAudioBookCaps.d.ts +9 -0
  104. package/dist/migrations/10-indexerNameAudioBookCaps.js +18 -0
  105. package/dist/migrations/10-indexerNameAudioBookCaps.js.map +1 -0
  106. package/dist/migrations/11-trackers.d.ts +9 -0
  107. package/dist/migrations/11-trackers.js +38 -0
  108. package/dist/migrations/11-trackers.js.map +1 -0
  109. package/dist/migrations/12-user-auth.d.ts +9 -0
  110. package/dist/migrations/12-user-auth.js +22 -0
  111. package/dist/migrations/12-user-auth.js.map +1 -0
  112. package/dist/migrations/13-settings.d.ts +9 -0
  113. package/dist/migrations/13-settings.js +23 -0
  114. package/dist/migrations/13-settings.js.map +1 -0
  115. package/dist/migrations/14-indexer-enabled-flag.d.ts +9 -0
  116. package/dist/migrations/14-indexer-enabled-flag.js +12 -0
  117. package/dist/migrations/14-indexer-enabled-flag.js.map +1 -0
  118. package/dist/migrations/15-remove-url-unique-constraint.d.ts +9 -0
  119. package/dist/migrations/15-remove-url-unique-constraint.js +14 -0
  120. package/dist/migrations/15-remove-url-unique-constraint.js.map +1 -0
  121. package/dist/migrations/16-prune-inactive-indexers.d.ts +9 -0
  122. package/dist/migrations/16-prune-inactive-indexers.js +17 -0
  123. package/dist/migrations/16-prune-inactive-indexers.js.map +1 -0
  124. package/dist/migrations/migrations.d.ts +13 -0
  125. package/dist/migrations/migrations.js +41 -0
  126. package/dist/migrations/migrations.js.map +1 -0
  127. package/dist/parseTorrent.d.ts +53 -0
  128. package/dist/parseTorrent.js +128 -0
  129. package/dist/parseTorrent.js.map +1 -0
  130. package/dist/pipeline.d.ts +41 -0
  131. package/dist/pipeline.js +578 -0
  132. package/dist/pipeline.js.map +1 -0
  133. package/dist/preFilter.d.ts +25 -0
  134. package/dist/preFilter.js +250 -0
  135. package/dist/preFilter.js.map +1 -0
  136. package/dist/problems/linking.d.ts +2 -0
  137. package/dist/problems/linking.js +80 -0
  138. package/dist/problems/linking.js.map +1 -0
  139. package/dist/problems/path.d.ts +22 -0
  140. package/dist/problems/path.js +96 -0
  141. package/dist/problems/path.js.map +1 -0
  142. package/dist/problems.d.ts +13 -0
  143. package/dist/problems.js +48 -0
  144. package/dist/problems.js.map +1 -0
  145. package/dist/pushNotifier.d.ts +19 -0
  146. package/dist/pushNotifier.js +137 -0
  147. package/dist/pushNotifier.js.map +1 -0
  148. package/dist/routes/baseApi.d.ts +2 -0
  149. package/dist/routes/baseApi.js +354 -0
  150. package/dist/routes/baseApi.js.map +1 -0
  151. package/dist/routes/indexerApi.d.ts +6 -0
  152. package/dist/routes/indexerApi.js +165 -0
  153. package/dist/routes/indexerApi.js.map +1 -0
  154. package/dist/routes/staticFrontendPlugin.d.ts +4 -0
  155. package/dist/routes/staticFrontendPlugin.js +61 -0
  156. package/dist/routes/staticFrontendPlugin.js.map +1 -0
  157. package/dist/runtimeConfig.d.ts +6 -0
  158. package/dist/runtimeConfig.js +27 -0
  159. package/dist/runtimeConfig.js.map +1 -0
  160. package/dist/searchee.d.ts +108 -0
  161. package/dist/searchee.js +690 -0
  162. package/dist/searchee.js.map +1 -0
  163. package/dist/server.d.ts +4 -0
  164. package/dist/server.js +65 -0
  165. package/dist/server.js.map +1 -0
  166. package/dist/services/indexerService.d.ts +96 -0
  167. package/dist/services/indexerService.js +287 -0
  168. package/dist/services/indexerService.js.map +1 -0
  169. package/dist/sessionCookies.d.ts +5 -0
  170. package/dist/sessionCookies.js +27 -0
  171. package/dist/sessionCookies.js.map +1 -0
  172. package/dist/startup.d.ts +25 -0
  173. package/dist/startup.js +157 -0
  174. package/dist/startup.js.map +1 -0
  175. package/dist/torrent.d.ts +69 -0
  176. package/dist/torrent.js +641 -0
  177. package/dist/torrent.js.map +1 -0
  178. package/dist/torznab.d.ts +60 -0
  179. package/dist/torznab.js +711 -0
  180. package/dist/torznab.js.map +1 -0
  181. package/dist/trpc/fastifyAdapter.d.ts +2 -0
  182. package/dist/trpc/fastifyAdapter.js +9 -0
  183. package/dist/trpc/fastifyAdapter.js.map +1 -0
  184. package/dist/trpc/index.d.ts +49 -0
  185. package/dist/trpc/index.js +53 -0
  186. package/dist/trpc/index.js.map +1 -0
  187. package/dist/trpc/routers/auth.d.ts +43 -0
  188. package/dist/trpc/routers/auth.js +116 -0
  189. package/dist/trpc/routers/auth.js.map +1 -0
  190. package/dist/trpc/routers/clients.d.ts +21 -0
  191. package/dist/trpc/routers/clients.js +65 -0
  192. package/dist/trpc/routers/clients.js.map +1 -0
  193. package/dist/trpc/routers/health.d.ts +17 -0
  194. package/dist/trpc/routers/health.js +24 -0
  195. package/dist/trpc/routers/health.js.map +1 -0
  196. package/dist/trpc/routers/index.d.ts +394 -0
  197. package/dist/trpc/routers/index.js +23 -0
  198. package/dist/trpc/routers/index.js.map +1 -0
  199. package/dist/trpc/routers/indexers.d.ts +75 -0
  200. package/dist/trpc/routers/indexers.js +79 -0
  201. package/dist/trpc/routers/indexers.js.map +1 -0
  202. package/dist/trpc/routers/jobs.d.ts +33 -0
  203. package/dist/trpc/routers/jobs.js +84 -0
  204. package/dist/trpc/routers/jobs.js.map +1 -0
  205. package/dist/trpc/routers/logs.d.ts +27 -0
  206. package/dist/trpc/routers/logs.js +91 -0
  207. package/dist/trpc/routers/logs.js.map +1 -0
  208. package/dist/trpc/routers/searchees.d.ts +51 -0
  209. package/dist/trpc/routers/searchees.js +156 -0
  210. package/dist/trpc/routers/searchees.js.map +1 -0
  211. package/dist/trpc/routers/settings.d.ts +83 -0
  212. package/dist/trpc/routers/settings.js +92 -0
  213. package/dist/trpc/routers/settings.js.map +1 -0
  214. package/dist/trpc/routers/stats.d.ts +42 -0
  215. package/dist/trpc/routers/stats.js +102 -0
  216. package/dist/trpc/routers/stats.js.map +1 -0
  217. package/dist/userAuth.d.ts +21 -0
  218. package/dist/userAuth.js +86 -0
  219. package/dist/userAuth.js.map +1 -0
  220. package/dist/utils/authUtils.d.ts +10 -0
  221. package/dist/utils/authUtils.js +24 -0
  222. package/dist/utils/authUtils.js.map +1 -0
  223. package/dist/utils/logWatcher.d.ts +28 -0
  224. package/dist/utils/logWatcher.js +229 -0
  225. package/dist/utils/logWatcher.js.map +1 -0
  226. package/dist/utils/object.d.ts +1 -0
  227. package/dist/utils/object.js +4 -0
  228. package/dist/utils/object.js.map +1 -0
  229. package/dist/utils.d.ts +172 -0
  230. package/dist/utils.js +648 -0
  231. package/dist/utils.js.map +1 -0
  232. package/dist/webui/assets/{FieldInfo-Bxj_j8SJ.js → FieldInfo-sRlPRNSK.js} +1 -1
  233. package/dist/webui/assets/{Page-C3rteCZt.js → Page-B68mlTwU.js} +1 -1
  234. package/dist/webui/assets/{array-field-DVSC6nHP.js → array-field-BCFMrvoU.js} +1 -1
  235. package/dist/webui/assets/{badge-DTZMtS0e.js → badge-C5YCxEzP.js} +1 -1
  236. package/dist/webui/assets/check-NQsw6yBl.js +1 -0
  237. package/dist/webui/assets/{chevron-down-CRy8M0kJ.js → chevron-down-8PGvFYxV.js} +1 -1
  238. package/dist/webui/assets/{clients-CW8oEZoQ.js → clients-DnVpwApe.js} +1 -1
  239. package/dist/webui/assets/{connect-YBNsnjWT.js → connect-wMg2zyz6.js} +1 -1
  240. package/dist/webui/assets/debug-BrjwiEi2.js +1 -0
  241. package/dist/webui/assets/{directories-BSK28RgR.js → directories-CHpJCWNR.js} +1 -1
  242. package/dist/webui/assets/{duration-field-C6xoSlJg.js → duration-field-DIkKt3iw.js} +1 -1
  243. package/dist/webui/assets/{general-lJJxZhH7.js → general-uZrUIxbI.js} +1 -1
  244. package/dist/webui/assets/health-_MuvAyjo.js +1 -0
  245. package/dist/webui/assets/index-B41DM2T5.css +1 -0
  246. package/dist/webui/assets/{index-C2cH1Gst.js → index-BBzHsn7u.js} +1 -1
  247. package/dist/webui/assets/{index-Bi48hI2z.js → index-Ncy0-Qo7.js} +3 -3
  248. package/dist/webui/assets/index-pKWy6v1P.js +1 -0
  249. package/dist/webui/assets/{jobs-CxmNab9w.js → jobs-B8eat0YU.js} +1 -1
  250. package/dist/webui/assets/{library-vaj2W8sE.js → library-BB0jQ8zn.js} +1 -1
  251. package/dist/webui/assets/{loader-circle-M0gu1gZ-.js → loader-circle-Bz67bJa3.js} +1 -1
  252. package/dist/webui/assets/logs-CeP28848.js +1 -0
  253. package/dist/webui/assets/{search-2R5sIdT8.js → search-BRBIrqaX.js} +1 -1
  254. package/dist/webui/assets/{select-zHgqMzLj.js → select-GZr6C6eZ.js} +1 -1
  255. package/dist/webui/assets/{select-field-BCqNLDrJ.js → select-field-CvT0SYk8.js} +1 -1
  256. package/dist/webui/assets/settings-0ZdYY8g_.js +1 -0
  257. package/dist/webui/assets/{submit-button-BtcnyggQ.js → submit-button-D7DKHqAq.js} +1 -1
  258. package/dist/webui/assets/{switch-G0W3uJVN.js → switch-BeMrf8sh.js} +1 -1
  259. package/dist/webui/assets/{switch-field-IBd9ORNq.js → switch-field-qMXHRKhx.js} +1 -1
  260. package/dist/webui/assets/{table-DvgJU7Gh.js → table-qEFWauuw.js} +1 -1
  261. package/dist/webui/assets/{test-tube-BIwmoM45.js → test-tube-DhD6uWdp.js} +1 -1
  262. package/dist/webui/assets/{text-field-DruSbGhy.js → text-field-ZnKHDUks.js} +1 -1
  263. package/dist/webui/assets/{time-BSMZjmyW.js → time-BM9K_Fbp.js} +1 -1
  264. package/dist/webui/assets/{trackers-D-OpAe63.js → trackers-BjJuAdX3.js} +1 -1
  265. package/dist/webui/assets/{use-form-validation-context-BkAfWAh0.js → use-form-validation-context-D2oA54L_.js} +1 -1
  266. package/dist/webui/assets/{use-settings-form-submit-CDRh-E9U.js → use-settings-form-submit-CXwtE1sI.js} +2 -2
  267. package/dist/webui/assets/useQuery-DD10sbzn.js +1 -0
  268. package/dist/webui/index.html +2 -2
  269. package/node_modules/@cross-seed/shared/dist/configSchema.d.ts.map +1 -1
  270. package/node_modules/@cross-seed/shared/dist/configSchema.js.map +1 -1
  271. package/node_modules/@cross-seed/shared/dist/tsconfig.tsbuildinfo +1 -1
  272. package/node_modules/@cross-seed/shared/dist/utils.d.ts +3 -0
  273. package/node_modules/@cross-seed/shared/dist/utils.d.ts.map +1 -1
  274. package/node_modules/@cross-seed/shared/dist/utils.js +11 -0
  275. package/node_modules/@cross-seed/shared/dist/utils.js.map +1 -1
  276. package/node_modules/@cross-seed/shared/package.json +3 -1
  277. package/package.json +18 -59
  278. package/LICENSE +0 -201
  279. package/README.md +0 -33
  280. package/dist/webui/assets/check-Bu3ldi63.js +0 -1
  281. package/dist/webui/assets/debug-mz8-WYZj.js +0 -1
  282. package/dist/webui/assets/health-CXbsVrie.js +0 -1
  283. package/dist/webui/assets/index-C-Ul7GNg.css +0 -1
  284. package/dist/webui/assets/index-Cc5bDmJr.js +0 -1
  285. package/dist/webui/assets/logs-Cu9RyKS0.js +0 -1
  286. package/dist/webui/assets/settings-CMYjpTbZ.js +0 -1
  287. package/dist/webui/assets/useQuery-A4Hv_4uX.js +0 -1
package/dist/inject.js ADDED
@@ -0,0 +1,594 @@
1
+ import chalk from "chalk";
2
+ import { stat, unlink } from "fs/promises";
3
+ import ms from "ms";
4
+ import { copyFile } from "fs/promises";
5
+ import path, { basename } from "path";
6
+ import { performActionWithoutMutex } from "./action.js";
7
+ import { byClientHostPriority, waitForTorrentToComplete, } from "./clients/TorrentClient.js";
8
+ import { appDir } from "./configuration.js";
9
+ import { Decision, InjectionResult, isAnyMatchedDecision, MediaType, SaveResult, TORRENT_CACHE_FOLDER, UNKNOWN_TRACKER, VIDEO_DISC_EXTENSIONS, } from "./constants.js";
10
+ import { assessCandidate } from "./decide.js";
11
+ import { getHostToNameMap } from "./indexers.js";
12
+ import { Label, logger } from "./logger.js";
13
+ import { findAllSearchees } from "./pipeline.js";
14
+ import { findBlockedStringInReleaseMaybe, logFilterReason, } from "./preFilter.js";
15
+ import { sendResultsNotification } from "./pushNotifier.js";
16
+ import { resultOf, resultOfErr } from "./Result.js";
17
+ import { getRuntimeConfig } from "./runtimeConfig.js";
18
+ import { createEnsembleSearchees, createSearcheeFromMetafile, getMediaType, } from "./searchee.js";
19
+ import { findAllTorrentFilesInDir, getTorrentSavePath, parseMetadataFromFilename, parseTorrentFromPath, } from "./torrent.js";
20
+ import { areMediaTitlesSimilar, comparing, exists, findFallback, formatAsList, getLogString, hasExt, humanReadableDate, isTruthy, Mutex, sanitizeInfoHash, withMutex, } from "./utils.js";
21
+ function getTorrentFilePathLog(torrentFilePath) {
22
+ const { infoHash } = parseMetadataFromFilename(basename(torrentFilePath));
23
+ return infoHash
24
+ ? chalk.bold.magenta(torrentFilePath.replace(infoHash, sanitizeInfoHash(infoHash)))
25
+ : chalk.bold.magenta(torrentFilePath);
26
+ }
27
+ async function deleteTorrentFileIfSafe(torrentFilePath) {
28
+ const filePathLog = getTorrentFilePathLog(torrentFilePath);
29
+ const { tracker, name, mediaType } = parseMetadataFromFilename(basename(torrentFilePath));
30
+ // we are confident cross-seed created the torrent,
31
+ // or it is intended for use with cross-seed
32
+ const isSafeToDelete = tracker && name && mediaType;
33
+ if (!isSafeToDelete) {
34
+ logger.warn({
35
+ label: Label.INJECT,
36
+ message: `Will not delete ${filePathLog}: missing metadata from filename`,
37
+ });
38
+ return;
39
+ }
40
+ logger.verbose({
41
+ label: Label.INJECT,
42
+ message: `Deleting ${filePathLog}`,
43
+ });
44
+ try {
45
+ await unlink(torrentFilePath);
46
+ }
47
+ catch (e) {
48
+ if (e.code !== "ENOENT") {
49
+ logger.error({
50
+ label: Label.INJECT,
51
+ message: `Failed to delete ${filePathLog}: ${e.message}`,
52
+ });
53
+ logger.debug(e);
54
+ }
55
+ }
56
+ }
57
+ async function deleteTorrentFileIfComplete(torrentFilePath, client, infoHash) {
58
+ if (await waitForTorrentToComplete(client, infoHash)) {
59
+ await deleteTorrentFileIfSafe(torrentFilePath);
60
+ }
61
+ else {
62
+ logger.warn({
63
+ label: Label.INJECT,
64
+ message: `Will not delete ${getTorrentFilePathLog(torrentFilePath)}: torrent is incomplete`,
65
+ });
66
+ }
67
+ }
68
+ async function whichSearcheesMatchTorrent(meta, searchees, blockList, ignoreTitles) {
69
+ const isSimilar = (searchee, meta) => areMediaTitlesSimilar(searchee.title, meta.title) ||
70
+ areMediaTitlesSimilar(searchee.title, meta.name) ||
71
+ areMediaTitlesSimilar(searchee.name, meta.name) ||
72
+ areMediaTitlesSimilar(searchee.name, meta.title);
73
+ let foundBlocked = false;
74
+ let fuzzyFail = false;
75
+ const matches = [];
76
+ for (const searchee of searchees) {
77
+ const { decision } = await assessCandidate(meta, searchee, new Set(), []);
78
+ if (!isAnyMatchedDecision(decision))
79
+ continue;
80
+ const blockedNote = findBlockedStringInReleaseMaybe(searchee, blockList);
81
+ if (blockedNote) {
82
+ logFilterReason(`it matches the blocklist: ${blockedNote}`, searchee, getMediaType(searchee));
83
+ foundBlocked = true;
84
+ continue;
85
+ }
86
+ if (!isSimilar(searchee, meta)) {
87
+ if (ignoreTitles) {
88
+ logger.warn({
89
+ label: Label.INJECT,
90
+ message: `Ignoring title mismatch for ${getLogString(meta, chalk.bold.white)} with ${getLogString(searchee, chalk.bold.white)}`,
91
+ });
92
+ }
93
+ else {
94
+ logger.warn({
95
+ label: Label.INJECT,
96
+ message: `Skipping match for ${getLogString(meta, chalk.bold.white)} with ${getLogString(searchee, chalk.bold.white)} due to title mismatch (use "${chalk.bold.white("cross-seed inject --ignore-titles")}" if this is an erroneous rejection)`,
97
+ });
98
+ fuzzyFail = true;
99
+ continue;
100
+ }
101
+ }
102
+ matches.push({ searchee, decision });
103
+ }
104
+ /**
105
+ * sort by client priority first for consistency, then
106
+ * full matches, then size only matches, then partial matches
107
+ * torrent, then data, then virtual
108
+ * prefer more files for partials
109
+ */
110
+ matches.sort(comparing((match) => byClientHostPriority(match.searchee.clientHost), (match) =>
111
+ // indexOf returns -1 for not found
112
+ -[Decision.MATCH_SIZE_ONLY, Decision.MATCH].indexOf(match.decision), (match) => !match.searchee.infoHash, (match) => !match.searchee.path, (match) => -match.searchee.files.length));
113
+ return { matches, foundBlocked, fuzzyFail };
114
+ }
115
+ async function injectInitialAction(meta, matches, tracker) {
116
+ let client;
117
+ const clientMatches = [];
118
+ let injectionResult = InjectionResult.FAILURE;
119
+ let matchedSearchee;
120
+ let matchedDecision;
121
+ let destinationDir;
122
+ let linkedNewFiles = false;
123
+ for (const { searchee, decision } of matches) {
124
+ const res = await performActionWithoutMutex(meta, decision, searchee, tracker, client);
125
+ const actionResult = res.actionResult;
126
+ clientMatches.push({ searchee, decision, actionResult });
127
+ if (actionResult === InjectionResult.FAILURE) {
128
+ if (res.linkedNewFiles)
129
+ break; // Since we couldn't unlink, process with the next job
130
+ continue;
131
+ }
132
+ if (actionResult === SaveResult.SAVED || !res.client)
133
+ continue;
134
+ if (res.linkedNewFiles)
135
+ linkedNewFiles = true;
136
+ if (injectionResult === InjectionResult.SUCCESS)
137
+ continue;
138
+ if (actionResult === InjectionResult.ALREADY_EXISTS) {
139
+ client = res.client;
140
+ destinationDir = res.destinationDir;
141
+ injectionResult = actionResult;
142
+ continue;
143
+ }
144
+ if (actionResult === InjectionResult.TORRENT_NOT_COMPLETE) {
145
+ if (injectionResult === InjectionResult.ALREADY_EXISTS)
146
+ continue;
147
+ client = res.client;
148
+ injectionResult = actionResult;
149
+ continue;
150
+ }
151
+ client = res.client;
152
+ destinationDir = res.destinationDir;
153
+ injectionResult = InjectionResult.SUCCESS;
154
+ matchedSearchee = searchee;
155
+ matchedDecision = decision;
156
+ }
157
+ return {
158
+ client,
159
+ clientMatches,
160
+ injectionResult,
161
+ matchedSearchee,
162
+ matchedDecision,
163
+ destinationDir,
164
+ linkedNewFiles,
165
+ };
166
+ }
167
+ function injectionFailed({ progress, injectionResult, summary, filePathLog, }) {
168
+ logger.error({
169
+ label: Label.INJECT,
170
+ message: `${progress} Failed to inject ${filePathLog} - ${chalk.red(injectionResult)}`,
171
+ });
172
+ summary.FAILED++;
173
+ }
174
+ async function injectFromStalledTorrent({ meta, client, clientMatches, tracker, injectionResult, progress, filePathLog, }) {
175
+ let injected = false;
176
+ let linkedNewFiles = false;
177
+ const stalledDecision = Decision.MATCH_PARTIAL; // Should always be considered partial
178
+ for (const { searchee } of clientMatches) {
179
+ const searcheeLog = getLogString(searchee, chalk.bold.white);
180
+ const res = await performActionWithoutMutex(meta, stalledDecision, searchee, tracker, client, { onlyCompleted: false });
181
+ if (res.actionResult === SaveResult.SAVED ||
182
+ res.actionResult === InjectionResult.TORRENT_NOT_COMPLETE) {
183
+ continue; // Not possible
184
+ }
185
+ linkedNewFiles = res.linkedNewFiles;
186
+ if (res.actionResult === InjectionResult.FAILURE) {
187
+ logger.error({
188
+ label: Label.INJECT,
189
+ message: `${progress} Failed to inject ${filePathLog} using stalled source ${searcheeLog} - ${chalk.yellow(injectionResult)}`,
190
+ });
191
+ continue;
192
+ }
193
+ if (res.actionResult === InjectionResult.ALREADY_EXISTS)
194
+ continue;
195
+ logger.warn({
196
+ label: Label.INJECT,
197
+ message: `${progress} Injected ${filePathLog} using stalled source ${searcheeLog}, you will need to resume or remove from client - ${chalk.green(injectionResult)}`,
198
+ });
199
+ injected = true;
200
+ }
201
+ if (injected)
202
+ return;
203
+ if (!(await client.isTorrentInClient(meta.infoHash)).orElse(false))
204
+ return;
205
+ if (linkedNewFiles) {
206
+ logger.info({
207
+ label: Label.INJECT,
208
+ message: `${progress} Rechecking ${filePathLog} as new files were linked - ${chalk.green(injectionResult)}`,
209
+ });
210
+ }
211
+ else {
212
+ logger.warn({
213
+ label: Label.INJECT,
214
+ message: `${progress} No new files linked for ${filePathLog}, resume or remove from client - ${chalk.yellow(injectionResult)}`,
215
+ });
216
+ }
217
+ }
218
+ async function injectionTorrentNotComplete(injectionAftermath) {
219
+ const { progress, torrentFilePath, injectionResult, summary, filePathLog } = injectionAftermath;
220
+ const { linkDirs } = getRuntimeConfig();
221
+ if (!linkDirs.length ||
222
+ (await stat(torrentFilePath)).mtimeMs >= Date.now() - ms("1 day")) {
223
+ // Normal case where source is likely still downloading
224
+ logger.warn({
225
+ label: Label.INJECT,
226
+ message: `${progress} Unable to inject ${filePathLog} - ${chalk.yellow(injectionResult)}`,
227
+ });
228
+ }
229
+ else {
230
+ // Since source is stalled, add to client paused so user can resume later if desired
231
+ // Try linking all possible matches as they may have different files
232
+ await injectFromStalledTorrent(injectionAftermath);
233
+ }
234
+ summary.INCOMPLETE_SEARCHEES++;
235
+ }
236
+ async function injectionAlreadyExists({ progress, torrentFilePath, client, clientMatches, injectionResult, summary, linkedNewFiles, meta, filePathLog, }) {
237
+ const isChecking = (await client.isTorrentChecking(meta.infoHash)).orElse(false);
238
+ let isComplete = (await client.isTorrentComplete(meta.infoHash)).orElse(false);
239
+ const decision = findFallback(clientMatches, [Decision.MATCH, Decision.MATCH_SIZE_ONLY], (match, decision) => match.decision === decision &&
240
+ match.actionResult === InjectionResult.ALREADY_EXISTS)?.decision ?? Decision.MATCH_PARTIAL;
241
+ if (linkedNewFiles) {
242
+ logger.info({
243
+ label: Label.INJECT,
244
+ message: `${progress} Rechecking ${filePathLog} as new files were linked - ${chalk.green(injectionResult)}`,
245
+ });
246
+ }
247
+ else if (isChecking) {
248
+ logger.info({
249
+ label: Label.INJECT,
250
+ message: `${progress} ${filePathLog} is being checked by client - ${chalk.green(injectionResult)}`,
251
+ });
252
+ summary.PROMISES.push(client.resumeInjection(meta, decision, {
253
+ checkOnce: false,
254
+ }));
255
+ }
256
+ else if (!isComplete && decision !== Decision.MATCH_PARTIAL) {
257
+ const finalCheckTime = (await stat(torrentFilePath)).mtimeMs + ms("1 day");
258
+ if (hasExt(meta.files, VIDEO_DISC_EXTENSIONS)) {
259
+ logger.warn({
260
+ label: Label.INJECT,
261
+ message: `${progress} Skipping recheck for ${filePathLog}: VIDEO_DISC_EXTENSIONS - ${chalk.yellow(injectionResult)}`,
262
+ });
263
+ }
264
+ else {
265
+ logger.info({
266
+ label: Label.INJECT,
267
+ message: `${progress} Rechecking ${filePathLog} as it's not complete but has all files (final check at ${humanReadableDate(finalCheckTime)}) - ${chalk.yellow(injectionResult)}`,
268
+ });
269
+ await client.recheckTorrent(meta.infoHash);
270
+ }
271
+ summary.PROMISES.push(client.resumeInjection(meta, decision, {
272
+ checkOnce: false,
273
+ }));
274
+ if (Date.now() >= finalCheckTime) {
275
+ isComplete = true; // Prevent infinite recheck in rare case of corrupted cross seed
276
+ }
277
+ }
278
+ else {
279
+ if (isComplete) {
280
+ logger.info({
281
+ label: Label.INJECT,
282
+ message: `${progress} ${filePathLog} - ${chalk.yellow(injectionResult)}`,
283
+ });
284
+ }
285
+ else {
286
+ logger.warn({
287
+ label: Label.INJECT,
288
+ message: `${progress} ${filePathLog} - ${chalk.yellow(injectionResult)} (incomplete)`,
289
+ });
290
+ summary.PROMISES.push(client.resumeInjection(meta, decision, {
291
+ checkOnce: true,
292
+ }));
293
+ }
294
+ }
295
+ summary.ALREADY_EXISTS++;
296
+ summary.INCOMPLETE_CANDIDATES += isComplete ? 0 : 1;
297
+ if (isComplete) {
298
+ await deleteTorrentFileIfSafe(torrentFilePath);
299
+ }
300
+ else {
301
+ summary.PROMISES.push(deleteTorrentFileIfComplete(torrentFilePath, client, meta.infoHash));
302
+ }
303
+ }
304
+ function injectionSuccess({ progress, torrentFilePath, client, injectionResult, summary, matchedSearchee, matchedDecision, meta, tracker, filePathLog, destinationDir, }, searchees) {
305
+ const { useClientTorrents } = getRuntimeConfig();
306
+ logger.info({
307
+ label: Label.INJECT,
308
+ message: `${progress} Injected ${filePathLog} - ${chalk.green(injectionResult)}`,
309
+ });
310
+ sendResultsNotification(matchedSearchee, [
311
+ [
312
+ { decision: matchedDecision, metafile: meta },
313
+ tracker,
314
+ injectionResult,
315
+ ],
316
+ ]);
317
+ summary.INJECTED++;
318
+ if (matchedDecision === Decision.MATCH_PARTIAL) {
319
+ summary.PARTIAL_MATCHES++;
320
+ }
321
+ else {
322
+ summary.FULL_MATCHES++;
323
+ }
324
+ summary.PROMISES.push(deleteTorrentFileIfComplete(torrentFilePath, client, meta.infoHash));
325
+ const res = createSearcheeFromMetafile(meta);
326
+ if (res.isOk()) {
327
+ searchees.push(useClientTorrents
328
+ ? {
329
+ ...res.unwrap(),
330
+ label: Label.INJECT,
331
+ clientHost: client.clientHost,
332
+ savePath: destinationDir,
333
+ }
334
+ : { ...res.unwrap(), label: Label.INJECT });
335
+ }
336
+ }
337
+ async function loadMetafile(torrentFilePath, progress, summary) {
338
+ const filePathLog = getTorrentFilePathLog(torrentFilePath);
339
+ let meta;
340
+ try {
341
+ meta = await parseTorrentFromPath(torrentFilePath);
342
+ }
343
+ catch (e) {
344
+ logger.error({
345
+ label: Label.INJECT,
346
+ message: `${progress} Failed to parse ${filePathLog}: ${e.message}`,
347
+ });
348
+ logger.debug(e);
349
+ return resultOfErr("FAILED_TO_PARSE");
350
+ }
351
+ const { tracker: trackerFromFilename } = parseMetadataFromFilename(basename(torrentFilePath));
352
+ if (trackerFromFilename) {
353
+ return resultOf({ meta, tracker: trackerFromFilename });
354
+ }
355
+ summary.FOUND_BAD_FORMAT = true;
356
+ const hostToName = await getHostToNameMap();
357
+ const trackerHost = meta.trackers.find((h) => hostToName.has(h));
358
+ if (trackerHost) {
359
+ return resultOf({ meta, tracker: hostToName.get(trackerHost) });
360
+ }
361
+ return resultOf({ meta, tracker: UNKNOWN_TRACKER });
362
+ }
363
+ async function injectSavedTorrent(progress, torrentFilePath, summary, searchees, ignoreTitles) {
364
+ const { blockList } = getRuntimeConfig();
365
+ const metafileResult = await loadMetafile(torrentFilePath, progress, summary);
366
+ if (metafileResult.isErr())
367
+ return;
368
+ const { meta, tracker } = metafileResult.unwrap();
369
+ const filePathLog = getTorrentFilePathLog(torrentFilePath);
370
+ const metaBlockedString = findBlockedStringInReleaseMaybe(meta, blockList);
371
+ if (metaBlockedString) {
372
+ logger.warn({
373
+ label: Label.INJECT,
374
+ message: `${progress} ${filePathLog} ${chalk.yellow(`is in the blockList: ${metaBlockedString}`)}`,
375
+ });
376
+ summary.BLOCKED++;
377
+ return;
378
+ }
379
+ const { matches, foundBlocked, fuzzyFail } = await whichSearcheesMatchTorrent(meta, searchees, blockList, ignoreTitles);
380
+ if (!matches.length) {
381
+ if (foundBlocked) {
382
+ logger.warn({
383
+ label: Label.INJECT,
384
+ message: `${progress} ${filePathLog} ${chalk.yellow(`has all matches in the blockList`)}`,
385
+ });
386
+ summary.BLOCKED++;
387
+ }
388
+ else {
389
+ logger.error({
390
+ label: Label.INJECT,
391
+ message: `${progress} ${filePathLog} ${chalk.red("has no matches")}`,
392
+ });
393
+ summary.UNMATCHED++;
394
+ }
395
+ if (fuzzyFail) {
396
+ logger.warn({
397
+ label: Label.INJECT,
398
+ message: `Will not delete ${filePathLog}: is has no matches due to title mismatch`,
399
+ });
400
+ }
401
+ else {
402
+ await deleteTorrentFileIfSafe(torrentFilePath);
403
+ }
404
+ return;
405
+ }
406
+ const { client, clientMatches, injectionResult, matchedSearchee, matchedDecision, destinationDir, linkedNewFiles, } = await injectInitialAction(meta, matches, tracker);
407
+ const injectionAftermath = {
408
+ progress,
409
+ torrentFilePath,
410
+ client,
411
+ injectionResult,
412
+ summary,
413
+ meta,
414
+ tracker,
415
+ clientMatches,
416
+ matchedSearchee,
417
+ matchedDecision,
418
+ destinationDir,
419
+ linkedNewFiles,
420
+ filePathLog,
421
+ };
422
+ switch (injectionResult) {
423
+ case InjectionResult.SUCCESS:
424
+ injectionSuccess(injectionAftermath, searchees);
425
+ break;
426
+ case InjectionResult.FAILURE:
427
+ injectionFailed(injectionAftermath);
428
+ break;
429
+ case InjectionResult.ALREADY_EXISTS:
430
+ await injectionAlreadyExists(injectionAftermath);
431
+ break;
432
+ case InjectionResult.TORRENT_NOT_COMPLETE:
433
+ await injectionTorrentNotComplete(injectionAftermath);
434
+ break;
435
+ }
436
+ }
437
+ function logInjectSummary(summary, flatLinking) {
438
+ const incompleteMsg = `${chalk.bold.yellow(summary.ALREADY_EXISTS)} existed in client${summary.INCOMPLETE_CANDIDATES
439
+ ? chalk.dim(` (${summary.INCOMPLETE_CANDIDATES} were incomplete)`)
440
+ : ""}`;
441
+ const resultMsg = formatAsList([
442
+ `Injected ${chalk.bold.green(summary.INJECTED)}/${chalk.bold.white(summary.TOTAL)} torrents`,
443
+ summary.FULL_MATCHES &&
444
+ `${chalk.bold.green(summary.FULL_MATCHES)} were full matches`,
445
+ summary.PARTIAL_MATCHES &&
446
+ `${chalk.bold.yellow(summary.PARTIAL_MATCHES)} were partial matches`,
447
+ summary.INCOMPLETE_SEARCHEES &&
448
+ `${chalk.bold.yellow(summary.INCOMPLETE_SEARCHEES)} had incomplete sources`,
449
+ summary.ALREADY_EXISTS && incompleteMsg,
450
+ summary.BLOCKED &&
451
+ `${chalk.bold.yellow(summary.BLOCKED)} were possibly blocklisted`,
452
+ summary.FAILED &&
453
+ `${chalk.bold.red(summary.FAILED)} failed to inject`,
454
+ summary.UNMATCHED &&
455
+ `${chalk.bold.red(summary.UNMATCHED)} had no matches`,
456
+ ].filter(isTruthy), { sort: false, type: "unit" });
457
+ logger.info({ label: Label.INJECT, message: chalk.cyan(resultMsg) });
458
+ if (summary.UNMATCHED > 0) {
459
+ logger.info({
460
+ label: Label.INJECT,
461
+ message: `Use "${chalk.bold.white("cross-seed diff")}" to get the reasons two torrents are not considered matches`,
462
+ });
463
+ }
464
+ if (summary.FOUND_BAD_FORMAT && !flatLinking) {
465
+ logger.warn({
466
+ label: Label.INJECT,
467
+ message: `Some torrents could be linked to linkDir/${UNKNOWN_TRACKER} - follow .torrent naming format in the docs to avoid this`,
468
+ });
469
+ }
470
+ }
471
+ function createSummary(total) {
472
+ return {
473
+ TOTAL: total,
474
+ INJECTED: 0,
475
+ FULL_MATCHES: 0,
476
+ PARTIAL_MATCHES: 0,
477
+ BLOCKED: 0,
478
+ ALREADY_EXISTS: 0,
479
+ INCOMPLETE_CANDIDATES: 0,
480
+ INCOMPLETE_SEARCHEES: 0,
481
+ FAILED: 0,
482
+ UNMATCHED: 0,
483
+ FOUND_BAD_FORMAT: false,
484
+ PROMISES: [],
485
+ };
486
+ }
487
+ export async function injectSavedTorrents() {
488
+ const { flatLinking, ignoreTitles, injectDir, outputDir } = getRuntimeConfig();
489
+ const targetDir = injectDir ?? outputDir;
490
+ const targetDirLog = chalk.bold.magenta(targetDir);
491
+ if (injectDir !== undefined) {
492
+ logger.warn({
493
+ label: Label.INJECT,
494
+ message: `Manually injecting torrents performs minimal filtering which slightly increases chances of false positives, see the docs for more info`,
495
+ });
496
+ }
497
+ if (ignoreTitles) {
498
+ logger.warn({
499
+ label: Label.INJECT,
500
+ message: `Ignoring torrent titles when looking for matches, this may result in false positives`,
501
+ });
502
+ }
503
+ const torrentFilePaths = await findAllTorrentFilesInDir(targetDir);
504
+ if (torrentFilePaths.length === 0) {
505
+ logger.info({
506
+ label: Label.INJECT,
507
+ message: `No torrent files are awaiting injection in ${targetDirLog}`,
508
+ });
509
+ return;
510
+ }
511
+ logger.info({
512
+ label: Label.INJECT,
513
+ message: `Found ${chalk.bold.white(torrentFilePaths.length)} torrent file(s) to inject in ${targetDirLog}`,
514
+ });
515
+ const summary = createSummary(torrentFilePaths.length);
516
+ const realSearchees = await findAllSearchees(Label.INJECT);
517
+ const ensembleSearchees = await createEnsembleSearchees(realSearchees, {
518
+ useFilters: false,
519
+ });
520
+ const searchees = [...realSearchees, ...ensembleSearchees];
521
+ for (const [i, torrentFilePath] of torrentFilePaths.entries()) {
522
+ const progress = chalk.blue(`(${i + 1}/${torrentFilePaths.length})`);
523
+ await withMutex(Mutex.CLIENT_INJECTION, { useQueue: true }, async () => {
524
+ return injectSavedTorrent(progress, torrentFilePath, summary, searchees, ignoreTitles ?? false);
525
+ });
526
+ }
527
+ logInjectSummary(summary, flatLinking);
528
+ if (injectDir !== undefined) {
529
+ logger.info({
530
+ label: Label.INJECT,
531
+ message: `Waiting on post-injection tasks to complete...`,
532
+ });
533
+ await Promise.all(summary.PROMISES);
534
+ }
535
+ }
536
+ export async function restoreFromTorrentCache() {
537
+ const { outputDir } = getRuntimeConfig();
538
+ const torrentFilePaths = await findAllTorrentFilesInDir(path.join(appDir(), TORRENT_CACHE_FOLDER));
539
+ if (torrentFilePaths.length === 0) {
540
+ logger.info("No .torrent files found to restore from cache");
541
+ return;
542
+ }
543
+ logger.info(`Found ${chalk.bold.white(torrentFilePaths.length)} .torrent files to restore from cache`);
544
+ let copied = 0;
545
+ const copyFromTorrentCache = async (torrentFilePath, destPath, infoHash) => {
546
+ if (await exists(destPath))
547
+ return;
548
+ await copyFile(torrentFilePath, destPath);
549
+ copied++;
550
+ if (copied % 1000 === 0) {
551
+ const destPathLog = infoHash
552
+ ? destPath.replace(infoHash, sanitizeInfoHash(infoHash))
553
+ : destPath;
554
+ logger.info(`${chalk.blue(`(${copied}/${torrentFilePaths.length})`)} ${chalk.bold.magenta(destPathLog)}`);
555
+ }
556
+ };
557
+ const hostToName = await getHostToNameMap();
558
+ let numMissingMetadata = 0;
559
+ for (const torrentFilePath of torrentFilePaths) {
560
+ try {
561
+ try {
562
+ const meta = await parseTorrentFromPath(torrentFilePath);
563
+ const infoHash = meta.infoHash;
564
+ const trackerHost = meta.trackers.find((h) => hostToName.has(h));
565
+ const destPath = getTorrentSavePath(meta, getMediaType(meta), trackerHost
566
+ ? hostToName.get(trackerHost)
567
+ : UNKNOWN_TRACKER, outputDir, { cached: true });
568
+ await copyFromTorrentCache(torrentFilePath, destPath, infoHash);
569
+ if (!trackerHost)
570
+ numMissingMetadata++;
571
+ }
572
+ catch (e) {
573
+ logger.error(chalk.bold.red(`Failure when processing ${torrentFilePath}, filename metadata will be unknown: ${e.message}`));
574
+ logger.error(e);
575
+ const baseName = basename(torrentFilePath);
576
+ const infoHash = baseName.split(".")[0];
577
+ const destFileName = `[${MediaType.OTHER}][${UNKNOWN_TRACKER}]${baseName}`;
578
+ const destPath = path.join(outputDir, destFileName);
579
+ await copyFromTorrentCache(torrentFilePath, destPath, infoHash);
580
+ numMissingMetadata++;
581
+ }
582
+ }
583
+ catch (e) {
584
+ logger.error(chalk.bold.red(`Failed to copy ${torrentFilePath}: ${e.message}`));
585
+ logger.error(e);
586
+ }
587
+ }
588
+ logger.info(`Copied ${chalk.bold.green(copied)}/${chalk.bold.white(torrentFilePaths.length)} .torrent files from cache to outputDir, run "${chalk.bold.white("cross-seed inject")}" to inject into client using your dataDirs`);
589
+ if (numMissingMetadata) {
590
+ logger.info(`Copied ${chalk.bold.yellow(numMissingMetadata)} .torrent files without filename metadata`);
591
+ }
592
+ logger.info(chalk.bold.yellow("Some of the restored torrents may be unregistered, you will need to remove them from your client after injecting"));
593
+ }
594
+ //# sourceMappingURL=inject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject.js","sourceRoot":"","sources":["../src/inject.ts"],"names":[],"mappings":"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"}
package/dist/jobs.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ import { RuntimeConfig } from "./runtimeConfig.js";
2
+ export declare enum JobName {
3
+ RSS = "rss",
4
+ SEARCH = "search",
5
+ UPDATE_INDEXER_CAPS = "updateIndexerCaps",
6
+ INJECT = "inject",
7
+ CLEANUP = "cleanup"
8
+ }
9
+ declare class Job {
10
+ name: JobName;
11
+ cadence: number;
12
+ exec: () => Promise<void>;
13
+ isActive: boolean;
14
+ runAheadOfSchedule: boolean;
15
+ delayNextRun: boolean;
16
+ configOverride: Partial<RuntimeConfig>;
17
+ shouldRunFn: () => boolean;
18
+ constructor(name: JobName, cadence: number, exec: () => Promise<void>, shouldRunFn?: () => boolean);
19
+ shouldRun(): boolean;
20
+ run(): Promise<boolean>;
21
+ }
22
+ export declare function getJobs(): Job[];
23
+ export declare function getJobLastRun(name: JobName): Promise<number | undefined>;
24
+ export declare function checkJobs(options?: {
25
+ isFirstRun: boolean;
26
+ useQueue: boolean;
27
+ }): Promise<void>;
28
+ export declare function jobsLoop(): Promise<void>;
29
+ export {};