@ekipnico/video-fetch 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 (49) hide show
  1. package/out/DownloadProvider.d.ts +22 -0
  2. package/out/DownloadProvider.js +7 -0
  3. package/out/DownloadProvider.js.map +1 -0
  4. package/out/VideoDownloadModule.d.ts +27 -0
  5. package/out/VideoDownloadModule.js +39 -0
  6. package/out/VideoDownloadModule.js.map +1 -0
  7. package/out/VideoDownloader.d.ts +22 -0
  8. package/out/VideoDownloader.js +42 -0
  9. package/out/VideoDownloader.js.map +1 -0
  10. package/out/index.d.ts +5 -0
  11. package/out/index.js +6 -0
  12. package/out/index.js.map +1 -0
  13. package/out/providers/YtDlpProvider.d.ts +36 -0
  14. package/out/providers/YtDlpProvider.js +215 -0
  15. package/out/providers/YtDlpProvider.js.map +1 -0
  16. package/out/schema/DownloadConfig.d.ts +24 -0
  17. package/out/schema/DownloadConfig.js +8 -0
  18. package/out/schema/DownloadConfig.js.map +1 -0
  19. package/out/schema/DownloadResult.d.ts +26 -0
  20. package/out/schema/DownloadResult.js +2 -0
  21. package/out/schema/DownloadResult.js.map +1 -0
  22. package/out/schema/VideoMetadata.d.ts +46 -0
  23. package/out/schema/VideoMetadata.js +35 -0
  24. package/out/schema/VideoMetadata.js.map +1 -0
  25. package/out/schema/index.d.ts +3 -0
  26. package/out/schema/index.js +4 -0
  27. package/out/schema/index.js.map +1 -0
  28. package/out/test/VideoDownloadModule.test.d.ts +1 -0
  29. package/out/test/VideoDownloadModule.test.js +61 -0
  30. package/out/test/VideoDownloadModule.test.js.map +1 -0
  31. package/out/test/VideoDownloader.test.d.ts +1 -0
  32. package/out/test/VideoDownloader.test.js +132 -0
  33. package/out/test/VideoDownloader.test.js.map +1 -0
  34. package/out/test/YtDlpProvider.test.d.ts +1 -0
  35. package/out/test/YtDlpProvider.test.js +215 -0
  36. package/out/test/YtDlpProvider.test.js.map +1 -0
  37. package/out/test/channel-download.test.d.ts +1 -0
  38. package/out/test/channel-download.test.js +269 -0
  39. package/out/test/channel-download.test.js.map +1 -0
  40. package/out/test/integration.test.d.ts +1 -0
  41. package/out/test/integration.test.js +120 -0
  42. package/out/test/integration.test.js.map +1 -0
  43. package/out/test/schema.test.d.ts +1 -0
  44. package/out/test/schema.test.js +62 -0
  45. package/out/test/schema.test.js.map +1 -0
  46. package/out/test/setup.test.d.ts +5 -0
  47. package/out/test/setup.test.js +7 -0
  48. package/out/test/setup.test.js.map +1 -0
  49. package/package.json +34 -0
@@ -0,0 +1,61 @@
1
+ import assert from 'node:assert';
2
+ import { Mesh } from 'mesh-ioc';
3
+ import { createVideoDownloadMesh, registerVideoDownloadServices } from '../VideoDownloadModule.js';
4
+ import { VideoDownloader } from '../VideoDownloader.js';
5
+ import { DownloadProvider } from '../DownloadProvider.js';
6
+ import { YtDlpProvider } from '../providers/YtDlpProvider.js';
7
+ describe('VideoDownloadModule', () => {
8
+ describe('createVideoDownloadMesh', () => {
9
+ it('creates a mesh with VideoDownloader', () => {
10
+ const mesh = createVideoDownloadMesh();
11
+ const downloader = mesh.resolve(VideoDownloader);
12
+ assert.ok(downloader instanceof VideoDownloader);
13
+ });
14
+ it('creates a mesh with DownloadProvider as YtDlpProvider', () => {
15
+ const mesh = createVideoDownloadMesh();
16
+ const provider = mesh.resolve(DownloadProvider);
17
+ assert.ok(provider instanceof YtDlpProvider);
18
+ assert.strictEqual(provider.name, 'yt-dlp');
19
+ });
20
+ it('creates new instances for each call', () => {
21
+ const mesh1 = createVideoDownloadMesh();
22
+ const mesh2 = createVideoDownloadMesh();
23
+ assert.notStrictEqual(mesh1, mesh2);
24
+ });
25
+ });
26
+ describe('registerVideoDownloadServices', () => {
27
+ it('registers VideoDownloader into existing mesh', () => {
28
+ const mesh = new Mesh('TestMesh');
29
+ registerVideoDownloadServices(mesh);
30
+ const downloader = mesh.resolve(VideoDownloader);
31
+ assert.ok(downloader instanceof VideoDownloader);
32
+ });
33
+ it('registers DownloadProvider as YtDlpProvider', () => {
34
+ const mesh = new Mesh('TestMesh');
35
+ registerVideoDownloadServices(mesh);
36
+ const provider = mesh.resolve(DownloadProvider);
37
+ assert.ok(provider instanceof YtDlpProvider);
38
+ });
39
+ it('allows resolving services multiple times', () => {
40
+ const mesh = new Mesh('TestMesh');
41
+ registerVideoDownloadServices(mesh);
42
+ const downloader1 = mesh.resolve(VideoDownloader);
43
+ const downloader2 = mesh.resolve(VideoDownloader);
44
+ // mesh-ioc typically returns the same instance
45
+ assert.strictEqual(downloader1, downloader2);
46
+ });
47
+ });
48
+ describe('DI wiring', () => {
49
+ it('VideoDownloader has provider injected', async () => {
50
+ const mesh = createVideoDownloadMesh();
51
+ const downloader = mesh.resolve(VideoDownloader);
52
+ // Test that provider is accessible through the downloader
53
+ // by calling a method that delegates to provider
54
+ // This would throw if provider wasn't injected
55
+ const isSupported = await downloader.isSupported('invalid-url');
56
+ // yt-dlp returns false for invalid URLs
57
+ assert.strictEqual(typeof isSupported, 'boolean');
58
+ });
59
+ });
60
+ });
61
+ //# sourceMappingURL=VideoDownloadModule.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VideoDownloadModule.test.js","sourceRoot":"","sources":["../../src/test/VideoDownloadModule.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,132 @@
1
+ import assert from 'node:assert';
2
+ import { Mesh } from 'mesh-ioc';
3
+ import { DownloadProvider } from '../DownloadProvider.js';
4
+ import { VideoDownloader } from '../VideoDownloader.js';
5
+ /**
6
+ * Mock provider for testing VideoDownloader without yt-dlp.
7
+ */
8
+ class MockDownloadProvider extends DownloadProvider {
9
+ constructor() {
10
+ super(...arguments);
11
+ this.name = 'mock';
12
+ this.mockDownloadResult = {
13
+ success: true,
14
+ videoDir: '/mock/mock123',
15
+ filePath: '/mock/mock123/video.mp4',
16
+ metadataPath: '/mock/mock123/meta.json',
17
+ format: 'mp4',
18
+ sizeBytes: 1000000,
19
+ duration: 120,
20
+ metadata: {
21
+ id: 'mock123',
22
+ platform: 'mock',
23
+ url: 'https://mock.com/video',
24
+ title: 'Mock Video',
25
+ description: 'A mock video',
26
+ uploader: 'Mock User',
27
+ duration: 120,
28
+ },
29
+ };
30
+ this.mockMetadata = {
31
+ id: 'mock123',
32
+ platform: 'mock',
33
+ url: 'https://mock.com/video',
34
+ title: 'Mock Video',
35
+ description: 'A mock video',
36
+ uploader: 'Mock User',
37
+ duration: 120,
38
+ };
39
+ this.mockIsSupported = true;
40
+ }
41
+ async download(url, config) {
42
+ this.lastDownloadUrl = url;
43
+ this.lastDownloadConfig = config;
44
+ return this.mockDownloadResult;
45
+ }
46
+ async extractMetadata(url) {
47
+ this.lastMetadataUrl = url;
48
+ return this.mockMetadata;
49
+ }
50
+ async isSupported(url) {
51
+ this.lastIsSupportedUrl = url;
52
+ return this.mockIsSupported;
53
+ }
54
+ }
55
+ describe('VideoDownloader', () => {
56
+ let downloader;
57
+ let mockProvider;
58
+ beforeEach(() => {
59
+ mockProvider = new MockDownloadProvider();
60
+ // Use mesh-ioc to properly inject the mock provider
61
+ const mesh = new Mesh('TestMesh');
62
+ mesh.constant(DownloadProvider, mockProvider);
63
+ mesh.service(VideoDownloader);
64
+ downloader = mesh.resolve(VideoDownloader);
65
+ });
66
+ describe('download', () => {
67
+ it('delegates to provider with merged config', async () => {
68
+ const result = await downloader.download('https://example.com/video');
69
+ assert.strictEqual(mockProvider.lastDownloadUrl, 'https://example.com/video');
70
+ assert.ok(mockProvider.lastDownloadConfig);
71
+ assert.strictEqual(mockProvider.lastDownloadConfig.format, 'best');
72
+ assert.strictEqual(mockProvider.lastDownloadConfig.quality, 'best');
73
+ });
74
+ it('merges partial config with defaults', async () => {
75
+ await downloader.download('https://example.com/video', {
76
+ quality: 720,
77
+ audioOnly: true,
78
+ });
79
+ assert.ok(mockProvider.lastDownloadConfig);
80
+ assert.strictEqual(mockProvider.lastDownloadConfig.quality, 720);
81
+ assert.strictEqual(mockProvider.lastDownloadConfig.audioOnly, true);
82
+ assert.strictEqual(mockProvider.lastDownloadConfig.format, 'best'); // default
83
+ assert.strictEqual(mockProvider.lastDownloadConfig.timeout, 600); // default
84
+ });
85
+ it('returns provider result', async () => {
86
+ const result = await downloader.download('https://example.com/video');
87
+ assert.strictEqual(result.success, true);
88
+ assert.strictEqual(result.videoDir, '/mock/mock123');
89
+ assert.strictEqual(result.filePath, '/mock/mock123/video.mp4');
90
+ assert.strictEqual(result.metadataPath, '/mock/mock123/meta.json');
91
+ assert.strictEqual(result.metadata.id, 'mock123');
92
+ });
93
+ });
94
+ describe('extractMetadata', () => {
95
+ it('delegates to provider', async () => {
96
+ const metadata = await downloader.extractMetadata('https://example.com/video');
97
+ assert.strictEqual(mockProvider.lastMetadataUrl, 'https://example.com/video');
98
+ assert.strictEqual(metadata.id, 'mock123');
99
+ assert.strictEqual(metadata.title, 'Mock Video');
100
+ });
101
+ it('returns provider metadata', async () => {
102
+ mockProvider.mockMetadata = {
103
+ id: 'custom123',
104
+ platform: 'youtube',
105
+ url: 'https://youtube.com/watch?v=custom123',
106
+ title: 'Custom Title',
107
+ description: 'Custom description',
108
+ uploader: 'Custom Channel',
109
+ duration: 300,
110
+ viewCount: 1000000,
111
+ };
112
+ const metadata = await downloader.extractMetadata('https://youtube.com/watch?v=custom123');
113
+ assert.strictEqual(metadata.id, 'custom123');
114
+ assert.strictEqual(metadata.platform, 'youtube');
115
+ assert.strictEqual(metadata.title, 'Custom Title');
116
+ assert.strictEqual(metadata.viewCount, 1000000);
117
+ });
118
+ });
119
+ describe('isSupported', () => {
120
+ it('delegates to provider', async () => {
121
+ const result = await downloader.isSupported('https://example.com/video');
122
+ assert.strictEqual(mockProvider.lastIsSupportedUrl, 'https://example.com/video');
123
+ assert.strictEqual(result, true);
124
+ });
125
+ it('returns provider result when not supported', async () => {
126
+ mockProvider.mockIsSupported = false;
127
+ const result = await downloader.isSupported('https://unsupported.com/video');
128
+ assert.strictEqual(result, false);
129
+ });
130
+ });
131
+ });
132
+ //# sourceMappingURL=VideoDownloader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VideoDownloader.test.js","sourceRoot":"","sources":["../../src/test/VideoDownloader.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,215 @@
1
+ import assert from 'node:assert';
2
+ import { YtDlpProvider } from '../providers/YtDlpProvider.js';
3
+ import { DEFAULT_DOWNLOAD_CONFIG } from '../schema/DownloadConfig.js';
4
+ describe('YtDlpProvider', () => {
5
+ describe('constructor', () => {
6
+ it('creates provider with default options', () => {
7
+ const provider = new YtDlpProvider();
8
+ assert.strictEqual(provider.name, 'yt-dlp');
9
+ });
10
+ it('accepts custom outputDir', () => {
11
+ const provider = new YtDlpProvider({
12
+ outputDir: '/custom/output',
13
+ });
14
+ assert.strictEqual(provider.name, 'yt-dlp');
15
+ });
16
+ it('accepts custom cookiesPath', () => {
17
+ const provider = new YtDlpProvider({
18
+ cookiesPath: '/path/to/cookies.txt',
19
+ });
20
+ assert.strictEqual(provider.name, 'yt-dlp');
21
+ });
22
+ });
23
+ describe('name property', () => {
24
+ it('returns yt-dlp', () => {
25
+ const provider = new YtDlpProvider();
26
+ assert.strictEqual(provider.name, 'yt-dlp');
27
+ });
28
+ });
29
+ });
30
+ /**
31
+ * Test subclass to expose private methods for testing.
32
+ */
33
+ class TestableYtDlpProvider extends YtDlpProvider {
34
+ testBuildDownloadArgs(url, outputPath, config) {
35
+ // @ts-expect-error - accessing private method for testing
36
+ return this.buildDownloadArgs(url, outputPath, config);
37
+ }
38
+ testMapMetadata(data, url) {
39
+ // @ts-expect-error - accessing private method for testing
40
+ return this.mapMetadata(data, url);
41
+ }
42
+ }
43
+ describe('YtDlpProvider (internal methods)', () => {
44
+ let provider;
45
+ beforeEach(() => {
46
+ provider = new TestableYtDlpProvider();
47
+ });
48
+ describe('buildDownloadArgs', () => {
49
+ it('builds basic args with default config', () => {
50
+ const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', DEFAULT_DOWNLOAD_CONFIG);
51
+ assert.ok(args.includes('-f'));
52
+ assert.ok(args.includes('"bestvideo+bestaudio/best"'));
53
+ assert.ok(args.includes('--merge-output-format'));
54
+ assert.ok(args.includes('mp4'));
55
+ assert.ok(args.includes('-o'));
56
+ assert.ok(args.includes('"/output/test.%(ext)s"'));
57
+ assert.ok(args.includes('"https://youtube.com/watch?v=test"'));
58
+ });
59
+ it('adds audio-only flags when audioOnly is true', () => {
60
+ const config = { ...DEFAULT_DOWNLOAD_CONFIG, audioOnly: true };
61
+ const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', config);
62
+ assert.ok(args.includes('-f'));
63
+ assert.ok(args.includes('"bestaudio[ext=m4a]/bestaudio"'));
64
+ assert.ok(args.includes('-x'));
65
+ });
66
+ it('adds quality filter when quality is specified', () => {
67
+ const config = { ...DEFAULT_DOWNLOAD_CONFIG, quality: 720 };
68
+ const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', config);
69
+ assert.ok(args.some(arg => arg.includes('height<=720')));
70
+ });
71
+ it('adds subtitle flags when includeSubtitles is true', () => {
72
+ const config = { ...DEFAULT_DOWNLOAD_CONFIG, includeSubtitles: true };
73
+ const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', config);
74
+ assert.ok(args.includes('--write-subs'));
75
+ });
76
+ it('adds subtitle language when specified', () => {
77
+ const config = { ...DEFAULT_DOWNLOAD_CONFIG, includeSubtitles: true, subtitleLang: 'en' };
78
+ const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', config);
79
+ assert.ok(args.includes('--write-subs'));
80
+ assert.ok(args.includes('--sub-lang'));
81
+ assert.ok(args.includes('en'));
82
+ });
83
+ it('adds rate limit when specified', () => {
84
+ const config = { ...DEFAULT_DOWNLOAD_CONFIG, rateLimit: 1000000 };
85
+ const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', config);
86
+ assert.ok(args.includes('-r'));
87
+ assert.ok(args.includes('1000000'));
88
+ });
89
+ it('adds extra args when specified', () => {
90
+ const config = { ...DEFAULT_DOWNLOAD_CONFIG, extraArgs: ['--verbose', '--no-playlist'] };
91
+ const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', config);
92
+ assert.ok(args.includes('--verbose'));
93
+ assert.ok(args.includes('--no-playlist'));
94
+ });
95
+ it('URL is always last argument', () => {
96
+ const args = provider.testBuildDownloadArgs('https://youtube.com/watch?v=test', '/output/test.%(ext)s', DEFAULT_DOWNLOAD_CONFIG);
97
+ const lastArg = args[args.length - 1];
98
+ assert.strictEqual(lastArg, '"https://youtube.com/watch?v=test"');
99
+ });
100
+ });
101
+ describe('mapMetadata', () => {
102
+ it('maps basic yt-dlp JSON output', () => {
103
+ const ytDlpData = {
104
+ id: 'test123',
105
+ extractor_key: 'Youtube',
106
+ webpage_url: 'https://youtube.com/watch?v=test123',
107
+ title: 'Test Video',
108
+ description: 'A test video description',
109
+ uploader: 'Test Channel',
110
+ duration: 120,
111
+ };
112
+ const metadata = provider.testMapMetadata(ytDlpData, 'https://youtube.com/watch?v=test123');
113
+ assert.strictEqual(metadata.id, 'test123');
114
+ assert.strictEqual(metadata.platform, 'youtube');
115
+ assert.strictEqual(metadata.url, 'https://youtube.com/watch?v=test123');
116
+ assert.strictEqual(metadata.title, 'Test Video');
117
+ assert.strictEqual(metadata.description, 'A test video description');
118
+ assert.strictEqual(metadata.uploader, 'Test Channel');
119
+ assert.strictEqual(metadata.duration, 120);
120
+ });
121
+ it('handles missing optional fields', () => {
122
+ const ytDlpData = {
123
+ id: 'test123',
124
+ title: 'Test Video',
125
+ duration: 60,
126
+ };
127
+ const metadata = provider.testMapMetadata(ytDlpData, 'https://example.com/video');
128
+ assert.strictEqual(metadata.id, 'test123');
129
+ assert.strictEqual(metadata.platform, 'unknown');
130
+ assert.strictEqual(metadata.url, 'https://example.com/video');
131
+ assert.strictEqual(metadata.title, 'Test Video');
132
+ assert.strictEqual(metadata.description, '');
133
+ assert.strictEqual(metadata.uploader, 'Unknown');
134
+ assert.strictEqual(metadata.duration, 60);
135
+ assert.strictEqual(metadata.viewCount, undefined);
136
+ assert.strictEqual(metadata.chapters, undefined);
137
+ });
138
+ it('maps engagement metrics', () => {
139
+ const ytDlpData = {
140
+ id: 'test123',
141
+ title: 'Test',
142
+ duration: 60,
143
+ view_count: 1000000,
144
+ like_count: 50000,
145
+ comment_count: 1500,
146
+ };
147
+ const metadata = provider.testMapMetadata(ytDlpData, 'https://example.com');
148
+ assert.strictEqual(metadata.viewCount, 1000000);
149
+ assert.strictEqual(metadata.likeCount, 50000);
150
+ assert.strictEqual(metadata.commentCount, 1500);
151
+ });
152
+ it('maps technical metadata', () => {
153
+ const ytDlpData = {
154
+ id: 'test123',
155
+ title: 'Test',
156
+ duration: 60,
157
+ width: 1920,
158
+ height: 1080,
159
+ fps: 30,
160
+ vcodec: 'vp9',
161
+ acodec: 'opus',
162
+ filesize: 50000000,
163
+ };
164
+ const metadata = provider.testMapMetadata(ytDlpData, 'https://example.com');
165
+ assert.strictEqual(metadata.width, 1920);
166
+ assert.strictEqual(metadata.height, 1080);
167
+ assert.strictEqual(metadata.fps, 30);
168
+ assert.strictEqual(metadata.vcodec, 'vp9');
169
+ assert.strictEqual(metadata.acodec, 'opus');
170
+ assert.strictEqual(metadata.filesize, 50000000);
171
+ });
172
+ it('maps chapters when present', () => {
173
+ const ytDlpData = {
174
+ id: 'test123',
175
+ title: 'Test',
176
+ duration: 600,
177
+ chapters: [
178
+ { title: 'Intro', start_time: 0, end_time: 60 },
179
+ { title: 'Main Content', start_time: 60, end_time: 500 },
180
+ { title: 'Outro', start_time: 500, end_time: 600 },
181
+ ],
182
+ };
183
+ const metadata = provider.testMapMetadata(ytDlpData, 'https://example.com');
184
+ assert.ok(metadata.chapters);
185
+ assert.strictEqual(metadata.chapters.length, 3);
186
+ assert.strictEqual(metadata.chapters[0].title, 'Intro');
187
+ assert.strictEqual(metadata.chapters[0].startTime, 0);
188
+ assert.strictEqual(metadata.chapters[0].endTime, 60);
189
+ assert.strictEqual(metadata.chapters[1].title, 'Main Content');
190
+ assert.strictEqual(metadata.chapters[2].title, 'Outro');
191
+ });
192
+ it('uses channel as uploader fallback', () => {
193
+ const ytDlpData = {
194
+ id: 'test123',
195
+ title: 'Test',
196
+ duration: 60,
197
+ channel: 'Channel Name',
198
+ };
199
+ const metadata = provider.testMapMetadata(ytDlpData, 'https://example.com');
200
+ assert.strictEqual(metadata.uploader, 'Channel Name');
201
+ assert.strictEqual(metadata.channel, 'Channel Name');
202
+ });
203
+ it('uses filesize_approx when filesize is not available', () => {
204
+ const ytDlpData = {
205
+ id: 'test123',
206
+ title: 'Test',
207
+ duration: 60,
208
+ filesize_approx: 25000000,
209
+ };
210
+ const metadata = provider.testMapMetadata(ytDlpData, 'https://example.com');
211
+ assert.strictEqual(metadata.filesize, 25000000);
212
+ });
213
+ });
214
+ });
215
+ //# sourceMappingURL=YtDlpProvider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"YtDlpProvider.test.js","sourceRoot":"","sources":["../../src/test/YtDlpProvider.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ import 'dotenv/config';