refactor: use URL instead of string where possible

This commit is contained in:
WebStreamr 2025-05-11 19:22:22 +00:00
parent 96dde8a634
commit 4787a1323d
No known key found for this signature in database
9 changed files with 20 additions and 20 deletions

View file

@ -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: {

View file

@ -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');
});
});

View file

@ -8,7 +8,7 @@ export class EmbedExtractors {
this.embedExtractors = embedExtractors;
}
readonly handle = async (url: string, language: string): Promise<StreamWithMeta> => {
readonly handle = async (url: URL, language: string): Promise<StreamWithMeta> => {
const embedExtractor = this.embedExtractors.find(embedExtractor => embedExtractor.supports(url));
if (undefined === embedExtractor) {

View file

@ -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: {

View file

@ -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<StreamWithMeta>;
readonly extract: (url: URL, language: string) => Promise<StreamWithMeta>;
}

View file

@ -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')),
);
};

View file

@ -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')),
);
};

View file

@ -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');
});
});

View file

@ -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:)?\/\//, ''));
}
}