youtube-knowledge-mcp 2.1.0 → 2.2.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 (344) hide show
  1. package/README.md +105 -34
  2. package/dist/brain-schemas.d.ts +10 -10
  3. package/dist/brain-schemas.d.ts.map +1 -1
  4. package/dist/brain-schemas.js +0 -4
  5. package/dist/brain-schemas.js.map +1 -1
  6. package/dist/http/app.d.ts +16 -0
  7. package/dist/http/app.d.ts.map +1 -0
  8. package/dist/http/app.js +176 -0
  9. package/dist/http/app.js.map +1 -0
  10. package/dist/http/auth.d.ts +38 -0
  11. package/dist/http/auth.d.ts.map +1 -0
  12. package/dist/http/auth.js +79 -0
  13. package/dist/http/auth.js.map +1 -0
  14. package/dist/http/config.d.ts +41 -0
  15. package/dist/http/config.d.ts.map +1 -0
  16. package/dist/http/config.js +65 -0
  17. package/dist/http/config.js.map +1 -0
  18. package/dist/http/rate-limiter.d.ts +24 -0
  19. package/dist/http/rate-limiter.d.ts.map +1 -0
  20. package/dist/http/rate-limiter.js +55 -0
  21. package/dist/http/rate-limiter.js.map +1 -0
  22. package/dist/http/sessions.d.ts +34 -0
  23. package/dist/http/sessions.d.ts.map +1 -0
  24. package/dist/http/sessions.js +62 -0
  25. package/dist/http/sessions.js.map +1 -0
  26. package/dist/http.d.ts +6 -48
  27. package/dist/http.d.ts.map +1 -1
  28. package/dist/http.js +35 -252
  29. package/dist/http.js.map +1 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +11 -517
  32. package/dist/index.js.map +1 -1
  33. package/dist/prompts-brain.d.ts +4 -0
  34. package/dist/prompts-brain.d.ts.map +1 -0
  35. package/dist/prompts-brain.js +48 -0
  36. package/dist/prompts-brain.js.map +1 -0
  37. package/dist/prompts-research.d.ts +4 -0
  38. package/dist/prompts-research.d.ts.map +1 -0
  39. package/dist/prompts-research.js +74 -0
  40. package/dist/prompts-research.js.map +1 -0
  41. package/dist/prompts-shared.d.ts +13 -0
  42. package/dist/prompts-shared.d.ts.map +1 -0
  43. package/dist/prompts-shared.js +7 -0
  44. package/dist/prompts-shared.js.map +1 -0
  45. package/dist/prompts.d.ts.map +1 -1
  46. package/dist/prompts.js +5 -100
  47. package/dist/prompts.js.map +1 -1
  48. package/dist/registry/brain-tools.d.ts +4 -0
  49. package/dist/registry/brain-tools.d.ts.map +1 -0
  50. package/dist/registry/brain-tools.js +104 -0
  51. package/dist/registry/brain-tools.js.map +1 -0
  52. package/dist/registry/channel-tools.d.ts +4 -0
  53. package/dist/registry/channel-tools.d.ts.map +1 -0
  54. package/dist/registry/channel-tools.js +53 -0
  55. package/dist/registry/channel-tools.js.map +1 -0
  56. package/dist/registry/health-tools.d.ts +4 -0
  57. package/dist/registry/health-tools.d.ts.map +1 -0
  58. package/dist/registry/health-tools.js +21 -0
  59. package/dist/registry/health-tools.js.map +1 -0
  60. package/dist/registry/index.d.ts +8 -0
  61. package/dist/registry/index.d.ts.map +1 -0
  62. package/dist/registry/index.js +27 -0
  63. package/dist/registry/index.js.map +1 -0
  64. package/dist/registry/library-tools.d.ts +4 -0
  65. package/dist/registry/library-tools.d.ts.map +1 -0
  66. package/dist/registry/library-tools.js +116 -0
  67. package/dist/registry/library-tools.js.map +1 -0
  68. package/dist/registry/media-tools.d.ts +4 -0
  69. package/dist/registry/media-tools.d.ts.map +1 -0
  70. package/dist/registry/media-tools.js +100 -0
  71. package/dist/registry/media-tools.js.map +1 -0
  72. package/dist/registry/thumbnail-tools.d.ts +7 -0
  73. package/dist/registry/thumbnail-tools.d.ts.map +1 -0
  74. package/dist/registry/thumbnail-tools.js +72 -0
  75. package/dist/registry/thumbnail-tools.js.map +1 -0
  76. package/dist/registry/transcript-tools.d.ts +4 -0
  77. package/dist/registry/transcript-tools.d.ts.map +1 -0
  78. package/dist/registry/transcript-tools.js +68 -0
  79. package/dist/registry/transcript-tools.js.map +1 -0
  80. package/dist/registry/types.d.ts +41 -0
  81. package/dist/registry/types.d.ts.map +1 -0
  82. package/dist/registry/types.js +17 -0
  83. package/dist/registry/types.js.map +1 -0
  84. package/dist/registry/video-tools.d.ts +4 -0
  85. package/dist/registry/video-tools.d.ts.map +1 -0
  86. package/dist/registry/video-tools.js +101 -0
  87. package/dist/registry/video-tools.js.map +1 -0
  88. package/dist/resources.d.ts.map +1 -1
  89. package/dist/resources.js +13 -10
  90. package/dist/resources.js.map +1 -1
  91. package/dist/schemas.d.ts +11 -2
  92. package/dist/schemas.d.ts.map +1 -1
  93. package/dist/schemas.js +5 -0
  94. package/dist/schemas.js.map +1 -1
  95. package/dist/thumbnail-resource.d.ts +8 -0
  96. package/dist/thumbnail-resource.d.ts.map +1 -0
  97. package/dist/thumbnail-resource.js +38 -0
  98. package/dist/thumbnail-resource.js.map +1 -0
  99. package/dist/thumbnail-schemas.d.ts +512 -0
  100. package/dist/thumbnail-schemas.d.ts.map +1 -0
  101. package/dist/thumbnail-schemas.js +95 -0
  102. package/dist/thumbnail-schemas.js.map +1 -0
  103. package/dist/tools/batch.js +1 -1
  104. package/dist/tools/batch.js.map +1 -1
  105. package/dist/tools/build-brain.js +1 -1
  106. package/dist/tools/build-brain.js.map +1 -1
  107. package/dist/tools/check-health.d.ts +2 -0
  108. package/dist/tools/check-health.d.ts.map +1 -1
  109. package/dist/tools/check-health.js +9 -0
  110. package/dist/tools/check-health.js.map +1 -1
  111. package/dist/tools/clips.d.ts +9 -41
  112. package/dist/tools/clips.d.ts.map +1 -1
  113. package/dist/tools/clips.js +52 -128
  114. package/dist/tools/clips.js.map +1 -1
  115. package/dist/tools/fetch-channel-thumbnails.d.ts +179 -0
  116. package/dist/tools/fetch-channel-thumbnails.d.ts.map +1 -0
  117. package/dist/tools/fetch-channel-thumbnails.js +123 -0
  118. package/dist/tools/fetch-channel-thumbnails.js.map +1 -0
  119. package/dist/tools/fetch-videos.d.ts +3 -0
  120. package/dist/tools/fetch-videos.d.ts.map +1 -1
  121. package/dist/tools/fetch-videos.js +3 -0
  122. package/dist/tools/fetch-videos.js.map +1 -1
  123. package/dist/tools/frames-subtitles.d.ts +44 -0
  124. package/dist/tools/frames-subtitles.d.ts.map +1 -0
  125. package/dist/tools/frames-subtitles.js +104 -0
  126. package/dist/tools/frames-subtitles.js.map +1 -0
  127. package/dist/tools/get-channel-info.d.ts +2 -0
  128. package/dist/tools/get-channel-info.d.ts.map +1 -1
  129. package/dist/tools/get-channel-info.js +8 -1
  130. package/dist/tools/get-channel-info.js.map +1 -1
  131. package/dist/tools/get-playlist-info.d.ts.map +1 -1
  132. package/dist/tools/get-playlist-info.js +1 -0
  133. package/dist/tools/get-playlist-info.js.map +1 -1
  134. package/dist/tools/get-thumbnail.d.ts +38 -0
  135. package/dist/tools/get-thumbnail.d.ts.map +1 -0
  136. package/dist/tools/get-thumbnail.js +152 -0
  137. package/dist/tools/get-thumbnail.js.map +1 -0
  138. package/dist/tools/get-transcript.d.ts.map +1 -1
  139. package/dist/tools/get-transcript.js +2 -14
  140. package/dist/tools/get-transcript.js.map +1 -1
  141. package/dist/tools/library.d.ts.map +1 -1
  142. package/dist/tools/library.js +13 -3
  143. package/dist/tools/library.js.map +1 -1
  144. package/dist/tools/list-channel-thumbnails.d.ts +235 -0
  145. package/dist/tools/list-channel-thumbnails.d.ts.map +1 -0
  146. package/dist/tools/list-channel-thumbnails.js +79 -0
  147. package/dist/tools/list-channel-thumbnails.js.map +1 -0
  148. package/dist/tools/save-to-library.d.ts.map +1 -1
  149. package/dist/tools/save-to-library.js +5 -1
  150. package/dist/tools/save-to-library.js.map +1 -1
  151. package/dist/tools/search-channels.d.ts +6 -0
  152. package/dist/tools/search-channels.d.ts.map +1 -1
  153. package/dist/tools/search-transcript.d.ts.map +1 -1
  154. package/dist/tools/search-transcript.js +6 -13
  155. package/dist/tools/search-transcript.js.map +1 -1
  156. package/dist/tools/search-videos.d.ts +3 -0
  157. package/dist/tools/search-videos.d.ts.map +1 -1
  158. package/dist/utils/batches.d.ts +15 -0
  159. package/dist/utils/batches.d.ts.map +1 -0
  160. package/dist/utils/batches.js +31 -0
  161. package/dist/utils/batches.js.map +1 -0
  162. package/dist/utils/brain-build.d.ts.map +1 -1
  163. package/dist/utils/brain-build.js +1 -12
  164. package/dist/utils/brain-build.js.map +1 -1
  165. package/dist/utils/brain-index.d.ts.map +1 -1
  166. package/dist/utils/brain-index.js +3 -2
  167. package/dist/utils/brain-index.js.map +1 -1
  168. package/dist/utils/brain-lock.d.ts +2 -18
  169. package/dist/utils/brain-lock.d.ts.map +1 -1
  170. package/dist/utils/brain-lock.js +4 -80
  171. package/dist/utils/brain-lock.js.map +1 -1
  172. package/dist/utils/brain-lookup.d.ts +8 -0
  173. package/dist/utils/brain-lookup.d.ts.map +1 -1
  174. package/dist/utils/brain-lookup.js +5 -31
  175. package/dist/utils/brain-lookup.js.map +1 -1
  176. package/dist/utils/brain-storage.d.ts.map +1 -1
  177. package/dist/utils/brain-storage.js +5 -5
  178. package/dist/utils/brain-storage.js.map +1 -1
  179. package/dist/utils/caption-probe.d.ts +7 -0
  180. package/dist/utils/caption-probe.d.ts.map +1 -0
  181. package/dist/utils/caption-probe.js +36 -0
  182. package/dist/utils/caption-probe.js.map +1 -0
  183. package/dist/utils/channel-images.d.ts +16 -0
  184. package/dist/utils/channel-images.d.ts.map +1 -0
  185. package/dist/utils/channel-images.js +35 -0
  186. package/dist/utils/channel-images.js.map +1 -0
  187. package/dist/utils/channel-lookup.d.ts +5 -0
  188. package/dist/utils/channel-lookup.d.ts.map +1 -0
  189. package/dist/utils/channel-lookup.js +37 -0
  190. package/dist/utils/channel-lookup.js.map +1 -0
  191. package/dist/utils/chapters.d.ts +11 -0
  192. package/dist/utils/chapters.d.ts.map +1 -0
  193. package/dist/utils/chapters.js +24 -0
  194. package/dist/utils/chapters.js.map +1 -0
  195. package/dist/utils/clips.d.ts.map +1 -1
  196. package/dist/utils/clips.js +18 -26
  197. package/dist/utils/clips.js.map +1 -1
  198. package/dist/utils/env.d.ts +26 -0
  199. package/dist/utils/env.d.ts.map +1 -0
  200. package/dist/utils/env.js +72 -0
  201. package/dist/utils/env.js.map +1 -0
  202. package/dist/utils/errors.d.ts +1 -1
  203. package/dist/utils/errors.d.ts.map +1 -1
  204. package/dist/utils/errors.js +20 -2
  205. package/dist/utils/errors.js.map +1 -1
  206. package/dist/utils/file-lock.d.ts +34 -0
  207. package/dist/utils/file-lock.d.ts.map +1 -0
  208. package/dist/utils/file-lock.js +91 -0
  209. package/dist/utils/file-lock.js.map +1 -0
  210. package/dist/utils/flat-listing.d.ts +89 -0
  211. package/dist/utils/flat-listing.d.ts.map +1 -0
  212. package/dist/utils/flat-listing.js +68 -0
  213. package/dist/utils/flat-listing.js.map +1 -0
  214. package/dist/utils/format.d.ts +1 -3
  215. package/dist/utils/format.d.ts.map +1 -1
  216. package/dist/utils/format.js +1 -5
  217. package/dist/utils/format.js.map +1 -1
  218. package/dist/utils/guard.d.ts +21 -0
  219. package/dist/utils/guard.d.ts.map +1 -0
  220. package/dist/utils/guard.js +105 -0
  221. package/dist/utils/guard.js.map +1 -0
  222. package/dist/utils/image-dimensions.d.ts +19 -0
  223. package/dist/utils/image-dimensions.d.ts.map +1 -0
  224. package/dist/utils/image-dimensions.js +93 -0
  225. package/dist/utils/image-dimensions.js.map +1 -0
  226. package/dist/utils/image-fetch.d.ts +31 -0
  227. package/dist/utils/image-fetch.d.ts.map +1 -0
  228. package/dist/utils/image-fetch.js +141 -0
  229. package/dist/utils/image-fetch.js.map +1 -0
  230. package/dist/utils/json-file.d.ts +14 -5
  231. package/dist/utils/json-file.d.ts.map +1 -1
  232. package/dist/utils/json-file.js +24 -9
  233. package/dist/utils/json-file.js.map +1 -1
  234. package/dist/utils/paths.d.ts +10 -0
  235. package/dist/utils/paths.d.ts.map +1 -1
  236. package/dist/utils/paths.js +14 -0
  237. package/dist/utils/paths.js.map +1 -1
  238. package/dist/utils/pattern.d.ts +30 -0
  239. package/dist/utils/pattern.d.ts.map +1 -0
  240. package/dist/utils/pattern.js +130 -0
  241. package/dist/utils/pattern.js.map +1 -0
  242. package/dist/utils/search-index.d.ts.map +1 -1
  243. package/dist/utils/search-index.js +9 -4
  244. package/dist/utils/search-index.js.map +1 -1
  245. package/dist/utils/storage.d.ts.map +1 -1
  246. package/dist/utils/storage.js +14 -8
  247. package/dist/utils/storage.js.map +1 -1
  248. package/dist/utils/subtitles.d.ts +7 -0
  249. package/dist/utils/subtitles.d.ts.map +1 -0
  250. package/dist/utils/subtitles.js +30 -0
  251. package/dist/utils/subtitles.js.map +1 -0
  252. package/dist/utils/thumbnail-entry.d.ts +19 -0
  253. package/dist/utils/thumbnail-entry.d.ts.map +1 -0
  254. package/dist/utils/thumbnail-entry.js +119 -0
  255. package/dist/utils/thumbnail-entry.js.map +1 -0
  256. package/dist/utils/thumbnail-fetch.d.ts +37 -0
  257. package/dist/utils/thumbnail-fetch.d.ts.map +1 -0
  258. package/dist/utils/thumbnail-fetch.js +89 -0
  259. package/dist/utils/thumbnail-fetch.js.map +1 -0
  260. package/dist/utils/thumbnail-ladder.d.ts +44 -0
  261. package/dist/utils/thumbnail-ladder.d.ts.map +1 -0
  262. package/dist/utils/thumbnail-ladder.js +68 -0
  263. package/dist/utils/thumbnail-ladder.js.map +1 -0
  264. package/dist/utils/thumbnail-listing.d.ts +16 -0
  265. package/dist/utils/thumbnail-listing.d.ts.map +1 -0
  266. package/dist/utils/thumbnail-listing.js +26 -0
  267. package/dist/utils/thumbnail-listing.js.map +1 -0
  268. package/dist/utils/thumbnail-paths.d.ts +20 -0
  269. package/dist/utils/thumbnail-paths.d.ts.map +1 -0
  270. package/dist/utils/thumbnail-paths.js +35 -0
  271. package/dist/utils/thumbnail-paths.js.map +1 -0
  272. package/dist/utils/thumbnail-store.d.ts +19 -0
  273. package/dist/utils/thumbnail-store.d.ts.map +1 -0
  274. package/dist/utils/thumbnail-store.js +125 -0
  275. package/dist/utils/thumbnail-store.js.map +1 -0
  276. package/dist/utils/transcript-cache.d.ts +20 -0
  277. package/dist/utils/transcript-cache.d.ts.map +1 -0
  278. package/dist/utils/transcript-cache.js +127 -0
  279. package/dist/utils/transcript-cache.js.map +1 -0
  280. package/dist/utils/transcript-search.d.ts +20 -0
  281. package/dist/utils/transcript-search.d.ts.map +1 -0
  282. package/dist/utils/transcript-search.js +35 -0
  283. package/dist/utils/transcript-search.js.map +1 -0
  284. package/dist/utils/transcript.d.ts +10 -31
  285. package/dist/utils/transcript.d.ts.map +1 -1
  286. package/dist/utils/transcript.js +2 -64
  287. package/dist/utils/transcript.js.map +1 -1
  288. package/dist/utils/validate-youtube.d.ts +35 -0
  289. package/dist/utils/validate-youtube.d.ts.map +1 -0
  290. package/dist/utils/validate-youtube.js +87 -0
  291. package/dist/utils/validate-youtube.js.map +1 -0
  292. package/dist/utils/validate.d.ts +11 -4
  293. package/dist/utils/validate.d.ts.map +1 -1
  294. package/dist/utils/validate.js +43 -36
  295. package/dist/utils/validate.js.map +1 -1
  296. package/dist/utils/version.d.ts +2 -0
  297. package/dist/utils/version.d.ts.map +1 -0
  298. package/dist/utils/version.js +19 -0
  299. package/dist/utils/version.js.map +1 -0
  300. package/dist/utils/youtube-channel.d.ts +44 -0
  301. package/dist/utils/youtube-channel.d.ts.map +1 -0
  302. package/dist/utils/youtube-channel.js +61 -0
  303. package/dist/utils/youtube-channel.js.map +1 -0
  304. package/dist/utils/youtube-download.d.ts +27 -0
  305. package/dist/utils/youtube-download.d.ts.map +1 -0
  306. package/dist/utils/youtube-download.js +118 -0
  307. package/dist/utils/youtube-download.js.map +1 -0
  308. package/dist/utils/youtube-schemas.d.ts +394 -0
  309. package/dist/utils/youtube-schemas.d.ts.map +1 -0
  310. package/dist/utils/youtube-schemas.js +118 -0
  311. package/dist/utils/youtube-schemas.js.map +1 -0
  312. package/dist/utils/youtube-search.d.ts +14 -0
  313. package/dist/utils/youtube-search.d.ts.map +1 -0
  314. package/dist/utils/youtube-search.js +39 -0
  315. package/dist/utils/youtube-search.js.map +1 -0
  316. package/dist/utils/youtube-url.d.ts +25 -0
  317. package/dist/utils/youtube-url.d.ts.map +1 -0
  318. package/dist/utils/youtube-url.js +75 -0
  319. package/dist/utils/youtube-url.js.map +1 -0
  320. package/dist/utils/youtube-video.d.ts +47 -0
  321. package/dist/utils/youtube-video.d.ts.map +1 -0
  322. package/dist/utils/youtube-video.js +98 -0
  323. package/dist/utils/youtube-video.js.map +1 -0
  324. package/dist/utils/youtube.d.ts +10 -122
  325. package/dist/utils/youtube.d.ts.map +1 -1
  326. package/dist/utils/youtube.js +11 -486
  327. package/dist/utils/youtube.js.map +1 -1
  328. package/dist/utils/ytdlp-env.d.ts +33 -0
  329. package/dist/utils/ytdlp-env.d.ts.map +1 -0
  330. package/dist/utils/ytdlp-env.js +121 -0
  331. package/dist/utils/ytdlp-env.js.map +1 -0
  332. package/dist/utils/ytdlp-limiter.d.ts +24 -0
  333. package/dist/utils/ytdlp-limiter.d.ts.map +1 -0
  334. package/dist/utils/ytdlp-limiter.js +69 -0
  335. package/dist/utils/ytdlp-limiter.js.map +1 -0
  336. package/dist/utils/ytdlp-parse.d.ts +13 -0
  337. package/dist/utils/ytdlp-parse.d.ts.map +1 -0
  338. package/dist/utils/ytdlp-parse.js +48 -0
  339. package/dist/utils/ytdlp-parse.js.map +1 -0
  340. package/dist/utils/ytdlp.d.ts +13 -18
  341. package/dist/utils/ytdlp.d.ts.map +1 -1
  342. package/dist/utils/ytdlp.js +21 -110
  343. package/dist/utils/ytdlp.js.map +1 -1
  344. package/package.json +2 -1
@@ -1,13 +1,14 @@
1
1
  import { join } from 'path';
2
2
  import { z } from 'zod';
3
- import { mkdir, readFile, rm, writeFile } from 'fs/promises';
3
+ import { readFile, rm } from 'fs/promises';
4
4
  import { existsSync } from 'fs';
5
5
  import { YouTubeError } from './errors.js';
6
6
  import { hasCachedTranscript } from './youtube.js';
7
7
  import { SearchIndex } from './search-index.js';
8
8
  import { libraryMetadataSchema, recordOfValid } from '../schemas.js';
9
- import { readJsonFile, writeJsonAtomic } from './json-file.js';
10
- import { dataDir } from './paths.js';
9
+ import { readJsonFile, writeFileAtomic, writeJsonAtomic } from './json-file.js';
10
+ import { dataDir, ensurePrivateDir } from './paths.js';
11
+ import { assertVideoId } from './validate.js';
11
12
  const LIBRARY_DIR = dataDir('library');
12
13
  const INDEX_FILE = dataDir('index.json');
13
14
  /**
@@ -21,8 +22,8 @@ export const libraryIndexSchema = z.object({
21
22
  items: recordOfValid(libraryMetadataSchema),
22
23
  });
23
24
  async function ensureDirectories() {
24
- await mkdir(dataDir(), { recursive: true });
25
- await mkdir(LIBRARY_DIR, { recursive: true });
25
+ await ensurePrivateDir(dataDir());
26
+ await ensurePrivateDir(LIBRARY_DIR);
26
27
  }
27
28
  async function loadIndex() {
28
29
  await ensureDirectories();
@@ -36,11 +37,11 @@ export async function saveToLibrary(options) {
36
37
  const { videoId, title, channel, url, content, contentType, tags = [] } = options;
37
38
  await ensureDirectories();
38
39
  const directory = itemDir(videoId);
39
- await mkdir(directory, { recursive: true });
40
+ await ensurePrivateDir(directory);
40
41
  // Save content
41
42
  const filename = contentType === 'summary' ? 'summary.md' : 'skill.md';
42
43
  const filePath = join(directory, filename);
43
- await writeFile(filePath, content, 'utf-8');
44
+ await writeFileAtomic(filePath, content);
44
45
  // Update metadata. Only the fields worth carrying forward need to survive
45
46
  // validation, so this is the metadata schema made optional field by field
46
47
  // rather than an "is an object" check that let anything through as metadata.
@@ -69,8 +70,13 @@ export async function saveToLibrary(options) {
69
70
  function withoutKey(record, key) {
70
71
  return Object.fromEntries(Object.entries(record).filter(([existing]) => existing !== key));
71
72
  }
73
+ /**
74
+ * The only place a video id becomes a path. Validated here, exactly as
75
+ * `brainDir` validates a channel id, because a value like `../../x` would
76
+ * otherwise write — and, on delete, recursively remove — outside the library.
77
+ */
72
78
  function itemDir(videoId) {
73
- return join(LIBRARY_DIR, videoId);
79
+ return join(LIBRARY_DIR, assertVideoId(videoId));
74
80
  }
75
81
  function metadataPath(videoId) {
76
82
  return join(itemDir(videoId), 'metadata.json');
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/utils/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/utils/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { TranscriptSegment } from './transcript.js';
2
+ /** Subtitle export: SRT and WebVTT for editors. */
3
+ /** 3723.5 -> "01:02:03,500" — the SRT wire format. */
4
+ export declare function formatSrtTimestamp(totalSeconds: number): string;
5
+ export declare function toSrt(segments: TranscriptSegment[]): string;
6
+ export declare function toVtt(segments: TranscriptSegment[]): string;
7
+ //# sourceMappingURL=subtitles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subtitles.d.ts","sourceRoot":"","sources":["../../src/utils/subtitles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,mDAAmD;AAEnD,sDAAsD;AACtD,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAS/D;AAED,wBAAgB,KAAK,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAY3D;AAED,wBAAgB,KAAK,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAW3D"}
@@ -0,0 +1,30 @@
1
+ /** Subtitle export: SRT and WebVTT for editors. */
2
+ /** 3723.5 -> "01:02:03,500" — the SRT wire format. */
3
+ export function formatSrtTimestamp(totalSeconds) {
4
+ const clamped = Math.max(0, totalSeconds);
5
+ const hours = Math.floor(clamped / 3600);
6
+ const minutes = Math.floor((clamped % 3600) / 60);
7
+ const seconds = Math.floor(clamped % 60);
8
+ const millis = Math.round((clamped - Math.floor(clamped)) * 1000);
9
+ const pad = (value, width = 2) => value.toString().padStart(width, '0');
10
+ return `${pad(hours)}:${pad(minutes)}:${pad(seconds)},${pad(millis, 3)}`;
11
+ }
12
+ export function toSrt(segments) {
13
+ return (segments
14
+ .map((segment, index) => [
15
+ index + 1,
16
+ `${formatSrtTimestamp(segment.start)} --> ${formatSrtTimestamp(segment.end)}`,
17
+ segment.text,
18
+ ].join('\n'))
19
+ .join('\n\n') + '\n');
20
+ }
21
+ export function toVtt(segments) {
22
+ const body = segments
23
+ .map((segment) => [
24
+ `${formatSrtTimestamp(segment.start).replace(',', '.')} --> ${formatSrtTimestamp(segment.end).replace(',', '.')}`,
25
+ segment.text,
26
+ ].join('\n'))
27
+ .join('\n\n');
28
+ return `WEBVTT\n\n${body}\n`;
29
+ }
30
+ //# sourceMappingURL=subtitles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subtitles.js","sourceRoot":"","sources":["../../src/utils/subtitles.ts"],"names":[],"mappings":"AAEA,mDAAmD;AAEnD,sDAAsD;AACtD,MAAM,UAAU,kBAAkB,CAAC,YAAoB;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAElE,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,KAAK,GAAG,CAAC,EAAU,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACxF,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,QAA6B;IACjD,OAAO,CACL,QAAQ;SACL,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CACtB;QACE,KAAK,GAAG,CAAC;QACT,GAAG,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QAC7E,OAAO,CAAC,IAAI;KACb,CAAC,IAAI,CAAC,IAAI,CAAC,CACb;SACA,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CACvB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,QAA6B;IACjD,MAAM,IAAI,GAAG,QAAQ;SAClB,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACf;QACE,GAAG,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,QAAQ,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;QACjH,OAAO,CAAC,IAAI;KACb,CAAC,IAAI,CAAC,IAAI,CAAC,CACb;SACA,IAAI,CAAC,MAAM,CAAC,CAAC;IAEhB,OAAO,aAAa,IAAI,IAAI,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { type ChannelImage, type ThumbnailEntry, type ThumbnailManifest, type ThumbnailQuality, type ThumbnailTab } from '../thumbnail-schemas.js';
2
+ import type { VideoListItem } from './youtube.js';
3
+ /** One thumbnail at a time: what is recorded about it, and how it is fetched and saved. */
4
+ export interface TabListing {
5
+ tab: ThumbnailTab;
6
+ videos: VideoListItem[];
7
+ }
8
+ /**
9
+ * Per-video entries, reconciled against the files actually on disk.
10
+ *
11
+ * A record that says `saved` whose file is missing or the wrong size goes back
12
+ * to `pending`; a video in today's listing that has no record gets one; and a
13
+ * record for a video not listed today is kept, since its file is still a
14
+ * thumbnail and the tab may simply not have been requested this time.
15
+ */
16
+ export declare function reconciled(channelId: string, existing: ThumbnailManifest | undefined, listings: TabListing[]): Promise<Map<string, ThumbnailEntry>>;
17
+ export declare function fetchOne(channelId: string, entry: ThumbnailEntry, quality: ThumbnailQuality): Promise<ThumbnailEntry>;
18
+ export declare function channelImage(channelId: string, kind: 'avatar' | 'banner', url: string | undefined, recorded: ChannelImage | undefined): Promise<ChannelImage | undefined>;
19
+ //# sourceMappingURL=thumbnail-entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbnail-entry.d.ts","sourceRoot":"","sources":["../../src/utils/thumbnail-entry.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAClB,MAAM,yBAAyB,CAAC;AASjC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,2FAA2F;AAE3F,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,YAAY,CAAC;IAClB,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAID;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,iBAAiB,GAAG,SAAS,EACvC,QAAQ,EAAE,UAAU,EAAE,GACrB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAetC;AA4BD,wBAAsB,QAAQ,CAC5B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,cAAc,CAAC,CAwBzB;AAED,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,QAAQ,GAAG,QAAQ,EACzB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,QAAQ,EAAE,YAAY,GAAG,SAAS,GACjC,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAkBnC"}
@@ -0,0 +1,119 @@
1
+ import { rm } from 'node:fs/promises';
2
+ import { imageFormatSchema, } from '../thumbnail-schemas.js';
3
+ import { throwIfAborted } from './context.js';
4
+ import { asYouTubeError } from './errors.js';
5
+ import { largestThumbnail } from './flat-listing.js';
6
+ import { MAX_IMAGE_BYTES } from './image-fetch.js';
7
+ import { writeFileAtomic } from './json-file.js';
8
+ import { climb, videoRungs } from './thumbnail-ladder.js';
9
+ import { channelImagePath, relativeFile, videoThumbnailPath } from './thumbnail-paths.js';
10
+ import { channelImageFile, entryPath, isIntact } from './thumbnail-store.js';
11
+ const ALL_FORMATS = imageFormatSchema.options;
12
+ /**
13
+ * Per-video entries, reconciled against the files actually on disk.
14
+ *
15
+ * A record that says `saved` whose file is missing or the wrong size goes back
16
+ * to `pending`; a video in today's listing that has no record gets one; and a
17
+ * record for a video not listed today is kept, since its file is still a
18
+ * thumbnail and the tab may simply not have been requested this time.
19
+ */
20
+ export async function reconciled(channelId, existing, listings) {
21
+ const entries = new Map();
22
+ for (const [videoId, recorded] of Object.entries(existing?.videos ?? {})) {
23
+ const intact = await isIntact(entryPath(channelId, recorded), recorded.bytes);
24
+ entries.set(videoId, intact ? recorded : { ...recorded, state: 'pending' });
25
+ }
26
+ for (const { tab, videos } of listings) {
27
+ for (const video of videos) {
28
+ if (!entries.has(video.id))
29
+ entries.set(video.id, pendingEntry(tab, video));
30
+ }
31
+ }
32
+ return entries;
33
+ }
34
+ function pendingEntry(tab, video) {
35
+ const listed = largestThumbnail(video.thumbnails ?? []);
36
+ const portrait = listed?.width !== null &&
37
+ listed?.width !== undefined &&
38
+ listed.height !== null &&
39
+ listed.height !== undefined &&
40
+ listed.height > listed.width;
41
+ return {
42
+ videoId: video.id,
43
+ title: video.title,
44
+ url: video.url,
45
+ tab,
46
+ isShort: tab === 'shorts' || portrait,
47
+ durationSeconds: video.duration,
48
+ ...(video.liveStatus === undefined ? {} : { liveStatus: video.liveStatus }),
49
+ ...(listed === undefined ? {} : { listedUrl: listed.url }),
50
+ ...(listed?.width === null || listed?.width === undefined ? {} : { listedWidth: listed.width }),
51
+ ...(listed?.height === null || listed?.height === undefined
52
+ ? {}
53
+ : { listedHeight: listed.height }),
54
+ state: 'pending',
55
+ };
56
+ }
57
+ export async function fetchOne(channelId, entry, quality) {
58
+ const listed = entry.listedUrl === undefined
59
+ ? undefined
60
+ : {
61
+ url: entry.listedUrl,
62
+ ...(entry.listedWidth === undefined ? {} : { width: entry.listedWidth }),
63
+ ...(entry.listedHeight === undefined ? {} : { height: entry.listedHeight }),
64
+ };
65
+ try {
66
+ const climbed = await climb(videoRungs(entry.videoId, listed, entry.isShort, quality), MAX_IMAGE_BYTES);
67
+ const path = videoThumbnailPath(channelId, entry.tab, entry.videoId, climbed.probe.format);
68
+ await replaceFile(path, climbed, (format) => videoThumbnailPath(channelId, entry.tab, entry.videoId, format));
69
+ return { ...withoutSaved(entry), state: 'saved', ...saved(channelId, path, climbed) };
70
+ }
71
+ catch (error) {
72
+ throwIfAborted();
73
+ return { ...withoutSaved(entry), state: 'failed', error: asYouTubeError(error).code };
74
+ }
75
+ }
76
+ export async function channelImage(channelId, kind, url, recorded) {
77
+ if (url === undefined)
78
+ return recorded;
79
+ if (recorded !== undefined &&
80
+ (await isIntact(channelImageFile(channelId, recorded), recorded.bytes))) {
81
+ return recorded;
82
+ }
83
+ try {
84
+ const climbed = await climb([{ variant: 'uncropped', url }], MAX_IMAGE_BYTES);
85
+ const path = channelImagePath(channelId, kind, climbed.probe.format);
86
+ await replaceFile(path, climbed, (format) => channelImagePath(channelId, kind, format));
87
+ return { kind, state: 'saved', ...saved(channelId, path, climbed) };
88
+ }
89
+ catch (error) {
90
+ throwIfAborted();
91
+ return { kind, state: 'failed', error: asYouTubeError(error).code };
92
+ }
93
+ }
94
+ /** Write the image, and remove an earlier file of the same name in another format. */
95
+ async function replaceFile(path, climbed, pathFor) {
96
+ await writeFileAtomic(path, climbed.bytes);
97
+ for (const format of ALL_FORMATS) {
98
+ if (format !== climbed.probe.format)
99
+ await rm(pathFor(format), { force: true });
100
+ }
101
+ }
102
+ function saved(channelId, path, climbed) {
103
+ return {
104
+ file: relativeFile(channelId, path),
105
+ sourceUrl: climbed.rung.url,
106
+ variant: climbed.rung.variant,
107
+ width: climbed.probe.width,
108
+ height: climbed.probe.height,
109
+ bytes: climbed.bytes.byteLength,
110
+ format: climbed.probe.format,
111
+ fetchedAt: new Date().toISOString(),
112
+ };
113
+ }
114
+ /** The entry with every field of a previous save removed, so a failure cannot keep stale sizes. */
115
+ function withoutSaved(entry) {
116
+ const { file: _file, sourceUrl: _sourceUrl, variant: _variant, width: _width, height: _height, bytes: _bytes, format: _format, fetchedAt: _fetchedAt, error: _error, ...rest } = entry;
117
+ return rest;
118
+ }
119
+ //# sourceMappingURL=thumbnail-entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbnail-entry.js","sourceRoot":"","sources":["../../src/utils/thumbnail-entry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { ThumbnailManifest, ThumbnailQuality, ThumbnailTab } from '../thumbnail-schemas.js';
2
+ import { type TabListing } from './thumbnail-entry.js';
3
+ export type { TabListing } from './thumbnail-entry.js';
4
+ import type { ChannelInfo } from './youtube.js';
5
+ /**
6
+ * Fetching a channel's thumbnails, resumably.
7
+ *
8
+ * Shaped like a brain build, and for the same reason: several hundred images
9
+ * is several hundred requests, so the job gets interrupted — cancelled by the
10
+ * client, throttled by YouTube, or killed with the editor. Per-image state
11
+ * rather than one flag, checkpoints rather than one write at the end, a
12
+ * failed image costing only itself, and a second call that continues.
13
+ */
14
+ export declare const CHECKPOINT_EVERY_ITEMS = 20;
15
+ export declare const RATE_LIMIT_TOLERANCE = 3;
16
+ export interface FetchThumbnailsOptions {
17
+ channel: ChannelInfo;
18
+ listings: TabListing[];
19
+ existing: ThumbnailManifest | undefined;
20
+ quality: ThumbnailQuality;
21
+ }
22
+ export interface FetchThumbnailsResult {
23
+ manifest: ThumbnailManifest;
24
+ considered: number;
25
+ fetched: number;
26
+ skipped: number;
27
+ failed: number;
28
+ failures: {
29
+ videoId: string;
30
+ tab: ThumbnailTab;
31
+ error: string;
32
+ }[];
33
+ stoppedEarly: boolean;
34
+ stopReason?: string;
35
+ }
36
+ export declare function fetchChannelThumbnails(options: FetchThumbnailsOptions): Promise<FetchThumbnailsResult>;
37
+ //# sourceMappingURL=thumbnail-fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbnail-fetch.d.ts","sourceRoot":"","sources":["../../src/utils/thumbnail-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAGjG,OAAO,EAAsC,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE3F,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAOvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;;;;;;;GAQG;AAEH,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,QAAQ,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACxC,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,YAAY,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClE,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CAiFhC"}
@@ -0,0 +1,89 @@
1
+ import { inBatches } from './batches.js';
2
+ import { reportProgress, throwIfAborted } from './context.js';
3
+ import { channelImage, fetchOne, reconciled } from './thumbnail-entry.js';
4
+ import { THUMBNAIL_MANIFEST_VERSION, computeThumbnailStats, writeThumbnailManifest, } from './thumbnail-store.js';
5
+ import { concurrencyState } from './ytdlp.js';
6
+ /**
7
+ * Fetching a channel's thumbnails, resumably.
8
+ *
9
+ * Shaped like a brain build, and for the same reason: several hundred images
10
+ * is several hundred requests, so the job gets interrupted — cancelled by the
11
+ * client, throttled by YouTube, or killed with the editor. Per-image state
12
+ * rather than one flag, checkpoints rather than one write at the end, a
13
+ * failed image costing only itself, and a second call that continues.
14
+ */
15
+ export const CHECKPOINT_EVERY_ITEMS = 20;
16
+ export const RATE_LIMIT_TOLERANCE = 3;
17
+ export async function fetchChannelThumbnails(options) {
18
+ const { channel, listings, existing, quality } = options;
19
+ const { channelId } = channel;
20
+ const createdAt = existing?.createdAt ?? new Date().toISOString();
21
+ const tabs = [...new Set([...(existing?.tabs ?? []), ...listings.map((l) => l.tab)])];
22
+ const entries = await reconciled(channelId, existing, listings);
23
+ const images = { avatar: existing?.avatar, banner: existing?.banner };
24
+ const save = async () => {
25
+ const manifest = {
26
+ version: THUMBNAIL_MANIFEST_VERSION,
27
+ channel,
28
+ tabs,
29
+ quality,
30
+ createdAt,
31
+ updatedAt: new Date().toISOString(),
32
+ ...(images.avatar === undefined ? {} : { avatar: images.avatar }),
33
+ ...(images.banner === undefined ? {} : { banner: images.banner }),
34
+ videos: Object.fromEntries(entries),
35
+ stats: computeThumbnailStats([...entries.values()]),
36
+ };
37
+ await writeThumbnailManifest(manifest);
38
+ return manifest;
39
+ };
40
+ images.avatar = await channelImage(channelId, 'avatar', channel.avatarUrl, images.avatar);
41
+ images.banner = await channelImage(channelId, 'banner', channel.bannerUrl, images.banner);
42
+ const outstanding = [...entries.values()].filter((e) => e.state !== 'saved');
43
+ const failures = [];
44
+ let attempted = 0;
45
+ let fetched = 0;
46
+ let consecutiveThrottles = 0;
47
+ let stopReason;
48
+ try {
49
+ await inBatches(outstanding, concurrencyState().limit, async (entry) => {
50
+ if (stopReason !== undefined)
51
+ return;
52
+ throwIfAborted();
53
+ const updated = await fetchOne(channelId, entry, quality);
54
+ entries.set(entry.videoId, updated);
55
+ attempted++;
56
+ if (updated.state === 'saved')
57
+ fetched++;
58
+ else
59
+ failures.push({
60
+ videoId: entry.videoId,
61
+ tab: entry.tab,
62
+ error: updated.error ?? 'FETCH_FAILED',
63
+ });
64
+ consecutiveThrottles = updated.error === 'RATE_LIMITED' ? consecutiveThrottles + 1 : 0;
65
+ if (consecutiveThrottles >= RATE_LIMIT_TOLERANCE)
66
+ stopReason = 'YouTube is rate limiting image downloads.';
67
+ reportProgress(attempted, outstanding.length, `Fetched ${attempted} of ${outstanding.length}`);
68
+ if (attempted % CHECKPOINT_EVERY_ITEMS === 0)
69
+ await save();
70
+ });
71
+ }
72
+ catch (error) {
73
+ // A cancelled job keeps what it fetched since the last checkpoint.
74
+ await save();
75
+ throw error;
76
+ }
77
+ const manifest = await save();
78
+ return {
79
+ manifest,
80
+ considered: entries.size,
81
+ fetched,
82
+ skipped: entries.size - outstanding.length,
83
+ failed: failures.length,
84
+ failures,
85
+ stoppedEarly: stopReason !== undefined,
86
+ ...(stopReason === undefined ? {} : { stopReason }),
87
+ };
88
+ }
89
+ //# sourceMappingURL=thumbnail-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbnail-fetch.js","sourceRoot":"","sources":["../../src/utils/thumbnail-fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { type ImageProbe } from './image-dimensions.js';
2
+ import type { ListedImage } from './flat-listing.js';
3
+ import type { ThumbnailQuality } from '../thumbnail-schemas.js';
4
+ /**
5
+ * Getting the best thumbnail YouTube will serve for one video.
6
+ *
7
+ * A flat channel listing offers each video's thumbnail at up to 720 pixels
8
+ * wide (verified against yt-dlp 2026.07.04). YouTube also serves a larger
9
+ * `maxresdefault.jpg` for many videos — the probed video returned one at
10
+ * 1280 wide — but not, as far as this code knows, for every video, and a
11
+ * missing one is not guaranteed to be a 404. So the ladder tries it and then
12
+ * checks what came back: an image is accepted only if it decodes and is wider
13
+ * than the listed one. Anything else falls through to the next rung. No
14
+ * behaviour of YouTube's is assumed that a rung could not verify for itself.
15
+ */
16
+ export interface Rung {
17
+ variant: string;
18
+ url: string;
19
+ /** Accept the image only if it decodes wider than this. */
20
+ mustExceedWidth?: number;
21
+ }
22
+ export interface Climbed {
23
+ bytes: Buffer;
24
+ probe: ImageProbe;
25
+ rung: Rung;
26
+ }
27
+ /**
28
+ * The rungs for one video, best first.
29
+ *
30
+ * Shorts are listed with portrait thumbnails; whether `maxresdefault` exists
31
+ * for a short, or is portrait when it does, is not verified, so a short uses
32
+ * its listed image and the small landscape fallback only.
33
+ */
34
+ export declare function videoRungs(videoId: string, listed: ListedImage | undefined, isShort: boolean, quality: ThumbnailQuality): Rung[];
35
+ /**
36
+ * Fetch rungs in order and return the first acceptable image.
37
+ *
38
+ * A rung is accepted when it downloads, decodes as an image this server reads,
39
+ * and — where the rung demands it — is wider than the listed image. A 404 or
40
+ * an unacceptable image moves to the next rung; rate limiting, a timeout or a
41
+ * cancelled request stops the climb immediately.
42
+ */
43
+ export declare function climb(rungs: Rung[], maxBytes: number): Promise<Climbed>;
44
+ //# sourceMappingURL=thumbnail-ladder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbnail-ladder.d.ts","sourceRoot":"","sources":["../../src/utils/thumbnail-ladder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,IAAI;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,IAAI,CAAC;CACZ;AAQD;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,gBAAgB,GACxB,IAAI,EAAE,CAaR;AAKD;;;;;;;GAOG;AACH,wBAAsB,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAgC7E"}
@@ -0,0 +1,68 @@
1
+ import { probeImage } from './image-dimensions.js';
2
+ import { fetchImage } from './image-fetch.js';
3
+ import { YouTubeError } from './errors.js';
4
+ const named = (videoId, variant, mustExceedWidth) => ({
5
+ variant,
6
+ url: `https://i.ytimg.com/vi/${videoId}/${variant}.jpg`,
7
+ ...(mustExceedWidth === undefined ? {} : { mustExceedWidth }),
8
+ });
9
+ /**
10
+ * The rungs for one video, best first.
11
+ *
12
+ * Shorts are listed with portrait thumbnails; whether `maxresdefault` exists
13
+ * for a short, or is portrait when it does, is not verified, so a short uses
14
+ * its listed image and the small landscape fallback only.
15
+ */
16
+ export function videoRungs(videoId, listed, isShort, quality) {
17
+ const listedRung = listed === undefined ? [] : [{ variant: 'listed', url: listed.url }];
18
+ const fallback = named(videoId, 'hqdefault');
19
+ if (isShort)
20
+ return [...listedRung, fallback];
21
+ if (quality === 'listed')
22
+ return [...listedRung, fallback];
23
+ const best = named(videoId, 'maxresdefault', listed?.width ?? 200);
24
+ // With no listing to beat, the smaller named sizes are worth trying too.
25
+ return listed === undefined
26
+ ? [best, named(videoId, 'sddefault'), fallback]
27
+ : [best, ...listedRung, fallback];
28
+ }
29
+ /** The reasons to stop climbing: they are about the client, not the rung. */
30
+ const ABORTING = new Set(['RATE_LIMITED', 'TIMEOUT', 'CANCELLED']);
31
+ /**
32
+ * Fetch rungs in order and return the first acceptable image.
33
+ *
34
+ * A rung is accepted when it downloads, decodes as an image this server reads,
35
+ * and — where the rung demands it — is wider than the listed image. A 404 or
36
+ * an unacceptable image moves to the next rung; rate limiting, a timeout or a
37
+ * cancelled request stops the climb immediately.
38
+ */
39
+ export async function climb(rungs, maxBytes) {
40
+ let last;
41
+ for (const rung of rungs) {
42
+ try {
43
+ const { bytes } = await fetchImage(rung.url, { maxBytes });
44
+ const probe = probeImage(bytes);
45
+ if (probe === undefined) {
46
+ last = new YouTubeError('FETCH_FAILED', 'The response was not an image this server can read.');
47
+ continue;
48
+ }
49
+ if (rung.mustExceedWidth !== undefined && probe.width <= rung.mustExceedWidth) {
50
+ last = new YouTubeError('NOT_FOUND', 'No larger image is available at that address.');
51
+ continue;
52
+ }
53
+ return { bytes, probe, rung };
54
+ }
55
+ catch (error) {
56
+ if (!(error instanceof YouTubeError))
57
+ throw error;
58
+ if (ABORTING.has(error.code))
59
+ throw error;
60
+ last = error;
61
+ }
62
+ }
63
+ throw (last ??
64
+ new YouTubeError('NOT_FOUND', 'No thumbnail address was available for this video.', {
65
+ nextStep: 'The listing carried no thumbnail; try again later.',
66
+ }));
67
+ }
68
+ //# sourceMappingURL=thumbnail-ladder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbnail-ladder.js","sourceRoot":"","sources":["../../src/utils/thumbnail-ladder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { ThumbnailTab } from '../thumbnail-schemas.js';
2
+ import type { TabListing } from './thumbnail-entry.js';
3
+ /**
4
+ * List each tab. The uploads tab must list — every channel has one, so a
5
+ * failure there is worth reporting. Whether yt-dlp lists an empty shorts or
6
+ * streams tab or refuses it is not verified, so those failures are recorded
7
+ * per tab and the run continues.
8
+ */
9
+ export declare function listTabs(channelUrl: string, tabs: ThumbnailTab[], maxVideos: number): Promise<{
10
+ listings: TabListing[];
11
+ tabErrors: {
12
+ tab: ThumbnailTab;
13
+ error: string;
14
+ }[];
15
+ }>;
16
+ //# sourceMappingURL=thumbnail-listing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbnail-listing.d.ts","sourceRoot":"","sources":["../../src/utils/thumbnail-listing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGvD;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,YAAY,EAAE,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;IAAC,SAAS,EAAE;QAAE,GAAG,EAAE,YAAY,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC,CAkBxF"}
@@ -0,0 +1,26 @@
1
+ import { asYouTubeError } from './errors.js';
2
+ import { listVideos } from './youtube.js';
3
+ /**
4
+ * List each tab. The uploads tab must list — every channel has one, so a
5
+ * failure there is worth reporting. Whether yt-dlp lists an empty shorts or
6
+ * streams tab or refuses it is not verified, so those failures are recorded
7
+ * per tab and the run continues.
8
+ */
9
+ export async function listTabs(channelUrl, tabs, maxVideos) {
10
+ const base = channelUrl.replace(/\/+$/, '');
11
+ const listings = [];
12
+ const tabErrors = [];
13
+ for (const tab of tabs) {
14
+ try {
15
+ const videos = (await listVideos(`${base}/${tab}`, maxVideos)).slice(0, maxVideos);
16
+ listings.push({ tab, videos });
17
+ }
18
+ catch (error) {
19
+ if (tab === 'videos')
20
+ throw error;
21
+ tabErrors.push({ tab, error: asYouTubeError(error).code });
22
+ }
23
+ }
24
+ return { listings, tabErrors };
25
+ }
26
+ //# sourceMappingURL=thumbnail-listing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbnail-listing.js","sourceRoot":"","sources":["../../src/utils/thumbnail-listing.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAsB,MAAM,cAAc,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,UAAkB,EAClB,IAAoB,EACpB,SAAiB;IAEjB,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAiB,EAAE,CAAC;IAClC,MAAM,SAAS,GAA2C,EAAE,CAAC;IAE7D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,MAAM,GAAoB,CAAC,MAAM,UAAU,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CACnF,CAAC,EACD,SAAS,CACV,CAAC;YACF,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,GAAG,KAAK,QAAQ;gBAAE,MAAM,KAAK,CAAC;YAClC,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC"}