From 4787a1323d8ec4dcbdccc2848d44624ab099455c Mon Sep 17 00:00:00 2001 From: WebStreamr <210764791+webstreamr@users.noreply.github.com> Date: Sun, 11 May 2025 19:22:22 +0000 Subject: [PATCH] refactor: use URL instead of string where possible --- src/embed-extractor/Dropload.ts | 8 ++++---- src/embed-extractor/EmbedExtractors.test.ts | 2 +- src/embed-extractor/EmbedExtractors.ts | 2 +- src/embed-extractor/SuperVideo.ts | 8 ++++---- src/embed-extractor/types.ts | 4 ++-- src/handler/KinoKiste.ts | 4 ++-- src/handler/MeineCloud.ts | 4 ++-- src/utils/embed.test.ts | 4 ++-- src/utils/embed.ts | 4 ++-- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/embed-extractor/Dropload.ts b/src/embed-extractor/Dropload.ts index be432b3..9e2eaea 100644 --- a/src/embed-extractor/Dropload.ts +++ b/src/embed-extractor/Dropload.ts @@ -12,10 +12,10 @@ export class Dropload implements EmbedExtractor { this.fetcher = fetcher; } - readonly supports = (url: string): boolean => null !== url.match(/dropload/); + readonly supports = (url: URL): boolean => null !== url.host.match(/dropload/); - readonly extract = async (url: string, language: string) => { - const normalizedUrl = url.replace('/e/', '').replace('/embed-', '/'); + readonly extract = async (url: URL, language: string) => { + const normalizedUrl = url.toString().replace('/e/', '').replace('/embed-', '/'); const html = await this.fetcher.text(normalizedUrl); const resolution = scanFromResolution((html.match(/(\d{3,}x\d{3,}),/) as string[])[1] as string); @@ -24,7 +24,7 @@ export class Dropload implements EmbedExtractor { const size = `${sizeMatch[1]} ${sizeMatch[2]}`; return { - url: extractUrlFromPacked(html, [/sources:\[{file:"(.*?)"/]), + url: extractUrlFromPacked(html, [/sources:\[{file:"(.*?)"/]).toString(), name: `WebStreamr ${resolution}`, title: `${this.label} | 💾 ${size} | ${iso2ToFlag(language)}`, behaviorHints: { diff --git a/src/embed-extractor/EmbedExtractors.test.ts b/src/embed-extractor/EmbedExtractors.test.ts index 32c5fe2..db356a3 100644 --- a/src/embed-extractor/EmbedExtractors.test.ts +++ b/src/embed-extractor/EmbedExtractors.test.ts @@ -4,6 +4,6 @@ describe('EmbedExtractors', () => { test('throws when no embed extractor can be found', () => { const embedExtractors = new EmbedExtractors([]); - expect(embedExtractors.handle('https://some-url.test', 'en')).rejects.toThrow('No embed extractor found that supports url https://some-url.test'); + expect(embedExtractors.handle(new URL('https://some-url.test'), 'en')).rejects.toThrow('No embed extractor found that supports url https://some-url.test'); }); }); diff --git a/src/embed-extractor/EmbedExtractors.ts b/src/embed-extractor/EmbedExtractors.ts index 352535b..e7fffa5 100644 --- a/src/embed-extractor/EmbedExtractors.ts +++ b/src/embed-extractor/EmbedExtractors.ts @@ -8,7 +8,7 @@ export class EmbedExtractors { this.embedExtractors = embedExtractors; } - readonly handle = async (url: string, language: string): Promise => { + readonly handle = async (url: URL, language: string): Promise => { const embedExtractor = this.embedExtractors.find(embedExtractor => embedExtractor.supports(url)); if (undefined === embedExtractor) { diff --git a/src/embed-extractor/SuperVideo.ts b/src/embed-extractor/SuperVideo.ts index 627fc64..5f23ad7 100644 --- a/src/embed-extractor/SuperVideo.ts +++ b/src/embed-extractor/SuperVideo.ts @@ -12,10 +12,10 @@ export class SuperVideo implements EmbedExtractor { this.fetcher = fetcher; } - readonly supports = (url: string): boolean => null !== url.match(/supervideo/); + readonly supports = (url: URL): boolean => null !== url.host.match(/supervideo/); - readonly extract = async (url: string, language: string) => { - const normalizedUrl = url.replace('/e/', '/').replace('/embed-', '/'); + readonly extract = async (url: URL, language: string) => { + const normalizedUrl = url.toString().replace('/e/', '/').replace('/embed-', '/'); const html = await this.fetcher.text(normalizedUrl); const resolutionAndSizeMatch = html.match(/(\d{3,}x\d{3,}), ([\d.]+) ?([GM]B)/) as string[]; @@ -23,7 +23,7 @@ export class SuperVideo implements EmbedExtractor { const size = `${resolutionAndSizeMatch[2]} ${resolutionAndSizeMatch[3]}`; return { - url: extractUrlFromPacked(html, [/sources:\[{file:"(.*?)"/]), + url: extractUrlFromPacked(html, [/sources:\[{file:"(.*?)"/]).toString(), name: `WebStreamr ${resolution}`, title: `${this.label} | 💾 ${size} | ${iso2ToFlag(language)}`, behaviorHints: { diff --git a/src/embed-extractor/types.ts b/src/embed-extractor/types.ts index cc24b34..dec662e 100644 --- a/src/embed-extractor/types.ts +++ b/src/embed-extractor/types.ts @@ -5,7 +5,7 @@ export interface EmbedExtractor { readonly label: string; - readonly supports: (url: string) => boolean; + readonly supports: (url: URL) => boolean; - readonly extract: (url: string, language: string) => Promise; + readonly extract: (url: URL, language: string) => Promise; } diff --git a/src/handler/KinoKiste.ts b/src/handler/KinoKiste.ts index 37cc28c..898ef18 100644 --- a/src/handler/KinoKiste.ts +++ b/src/handler/KinoKiste.ts @@ -40,9 +40,9 @@ export class KinoKiste implements Handler { $(`[data-num="${imdbId.series}x${imdbId.episode}"]`) .siblings('.mirrors') .children('[data-link]') - .map((_i, el) => ($(el).attr('data-link') as string).replace(/^(https:)?\/\//, 'https://')) + .map((_i, el) => new URL(($(el).attr('data-link') as string).replace(/^(https:)?\/\//, 'https://'))) .toArray() - .filter(embedUrl => embedUrl.match(/(dropload|supervideo)/)) + .filter(embedUrl => embedUrl.host.match(/(dropload|supervideo)/)) .map(embedUrl => this.embedExtractors.handle(embedUrl, 'de')), ); }; diff --git a/src/handler/MeineCloud.ts b/src/handler/MeineCloud.ts index acb06a6..7860f59 100644 --- a/src/handler/MeineCloud.ts +++ b/src/handler/MeineCloud.ts @@ -31,9 +31,9 @@ export class MeineCloud implements Handler { return fulfillAllPromises( $('[data-link!=""]') - .map((_i, el) => ($(el).attr('data-link') as string).replace(/^(https:)?\/\//, 'https://')) + .map((_i, el) => new URL(($(el).attr('data-link') as string).replace(/^(https:)?\/\//, 'https://'))) .toArray() - .filter(embedUrl => embedUrl.match(/(dropload|supervideo)/)) + .filter(embedUrl => embedUrl.host.match(/(dropload|supervideo)/)) .map(embedUrl => this.embedExtractors.handle(embedUrl, 'de')), ); }; diff --git a/src/utils/embed.test.ts b/src/utils/embed.test.ts index b773707..5bc206f 100644 --- a/src/utils/embed.test.ts +++ b/src/utils/embed.test.ts @@ -21,8 +21,8 @@ describe('extractUrlFromPacked', () => { }); test('finds link', async () => { - (unpack as jest.Mock).mockReturnValue('{sources:[{file:"https://streaming-url.mp4"}'); + (unpack as jest.Mock).mockReturnValue('{sources:[{file:"https://streaming.test/something.mp4"}'); - expect(extractUrlFromPacked('eval(function(p,a,c,k,e,d){...}))', [/sources:\[{file:"(.*?)"/])).toBe('https://streaming-url.mp4'); + expect(extractUrlFromPacked('eval(function(p,a,c,k,e,d){...}))', [/sources:\[{file:"(.*?)"/]).href).toBe('https://streaming.test/something.mp4'); }); }); diff --git a/src/utils/embed.ts b/src/utils/embed.ts index c2e3684..d0b9dae 100644 --- a/src/utils/embed.ts +++ b/src/utils/embed.ts @@ -1,6 +1,6 @@ import { unpack } from 'unpacker'; -export const extractUrlFromPacked = (html: string, linkRegExps: RegExp[]): string => { +export const extractUrlFromPacked = (html: string, linkRegExps: RegExp[]): URL => { const evalMatch = html.match(/eval\(function\(p,a,c,k,e,d\).*\)\)/); if (!evalMatch) { throw new Error(`No p.a.c.k.e.d string found`); @@ -11,7 +11,7 @@ export const extractUrlFromPacked = (html: string, linkRegExps: RegExp[]): strin for (const linkRegexp of linkRegExps) { const linkMatch = unpacked.match(linkRegexp); if (linkMatch && linkMatch[1]) { - return 'https://' + linkMatch[1].replace(/^(https:)?\/\//, ''); + return new URL('https://' + linkMatch[1].replace(/^(https:)?\/\//, '')); } }