feat(source): add XPrime

This commit is contained in:
WebStreamr 2025-08-15 10:35:20 +00:00
parent 9854d3b5b6
commit cfe38878d7
No known key found for this signature in database
18 changed files with 276 additions and 1 deletions

View file

@ -0,0 +1,29 @@
import winston from 'winston';
import { createTestContext } from '../test';
import { CountryCode } from '../types';
import { FetcherMock } from '../utils';
import { ExtractorRegistry } from './ExtractorRegistry';
import { XPrime } from './XPrime';
const logger = winston.createLogger({ transports: [new winston.transports.Console({ level: 'nope' })] });
const extractorRegistry = new ExtractorRegistry(logger, [new XPrime(new FetcherMock(`${__dirname}/__fixtures__/XPrime`))]);
const ctx = createTestContext();
describe('XPrime', () => {
test('unknown backend is ignored', async () => {
expect(await extractorRegistry.handle(ctx, new URL('https://backend.xprime.tv/unknown?name=Superman&year=2025'), CountryCode.en, 'Superman (2025)')).toMatchSnapshot();
});
test('primebox Superman', async () => {
expect(await extractorRegistry.handle(ctx, new URL('https://backend.xprime.tv/primebox?name=Superman&year=2025'), CountryCode.en, 'Superman (2025)')).toMatchSnapshot();
});
test('primebox Alien: Earth', async () => {
expect(await extractorRegistry.handle(ctx, new URL('https://backend.xprime.tv/primebox?name=Alien%3A%20Earth&year=2025&season=1&episode=1'), CountryCode.en, 'Alien: Earth')).toMatchSnapshot();
});
test('primebox not found', async () => {
expect(await extractorRegistry.handle(ctx, new URL('https://backend.xprime.tv/primebox?name=Jurassic%20World%20Rebirth&year=2025'), CountryCode.en, 'Jurassic World Rebirth (2025)')).toMatchSnapshot();
});
});

60
src/extractor/XPrime.ts Normal file
View file

@ -0,0 +1,60 @@
import { Context, CountryCode, Format, UrlResult } from '../types';
import { Fetcher } from '../utils';
import { Extractor } from './Extractor';
interface XPrimePrimeboxResponsePartial {
streams: Record<string, string>;
}
export class XPrime extends Extractor {
public readonly id = 'xprime';
public readonly label = 'XPrime';
public override readonly ttl: number = 10800000; // 3h
private readonly fetcher: Fetcher;
public constructor(fetcher: Fetcher) {
super();
this.fetcher = fetcher;
}
public supports(_ctx: Context, url: URL): boolean {
return null !== url.host.match(/xprime/);
}
protected async extractInternal(ctx: Context, url: URL, countryCode: CountryCode, title: string | undefined): Promise<UrlResult[]> {
const urlResults: UrlResult[] = [];
const referer = url.protocol + '//' + url.hostname.split('.').slice(-2).join('.'); // Strip subdomains
if (url.href.includes('primebox')) {
const jsonResponse = JSON.parse(await this.fetcher.text(ctx, url)) as XPrimePrimeboxResponsePartial;
for (const [resolution, stream] of Object.entries(jsonResponse.streams)) {
const url = new URL(stream);
urlResults.push({
url,
format: Format.mp4,
label: `${this.label} Primebox`,
sourceId: `${this.id}_${countryCode}_primebox`,
ttl: this.ttl,
meta: {
countryCodes: [countryCode],
bytes: parseInt((await this.fetcher.head(ctx, url, { headers: { Referer: referer }, minCacheTtl: this.ttl }))['content-length'] as string),
height: parseInt(resolution),
title: `${title}`,
},
requestHeaders: {
Referer: referer,
},
});
}
}
return urlResults;
};
}

View file

@ -0,0 +1 @@
{"accept-ranges":"bytes","access-control-allow-methods":"*","access-control-allow-origin":"https://xprime.tv","age":"189968","ali-swift-global-savetime":"1755063340","alt-svc":"h3=\":443\"; ma=86400","cache-control":"public, max-age=31536000, immutable","cdn-cache-control":"public, max-age=31536000, immutable","cf-cache-status":"MISS","cf-ray":"96f7f793caffd26c-FRA","connection":"close","content-disposition":"attachment;filename=Alien: Earth-S1E1-480P.mp4","content-length":"420170402","content-type":"video/mp4","date":"Fri, 15 Aug 2025 10:21:48 GMT","eagleid":"2ff617a417552533081123028e","etag":"\"C6A45A0457EDA758D7DF7576FF2FDB1C-12\"","last-modified":"Wed, 13 Aug 2025 05:30:23 GMT","nel":"{\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}","report-to":"{\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=iK6KXy00H4dsUV65PssAn7rKLgvq2C2cak5DPDyN0R%2BpG8MpU3RJIVMrmmf4Ux79jlRKXxBT3S%2Bjp210eZLTAkruPkqJBbm%2BRgrYNXnjwBaTOkkKhDwZC3Hdb6OKpX0sbnvb2YXyqsTpQ0786Z35AARB6RaQhms%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}","server":"cloudflare","server-timing":"cfL4;desc=\"?proto=TCP&rtt=0&min_rtt=0&rtt_var=0&sent=0&recv=0&lost=0&retrans=0&sent_bytes=0&recv_bytes=0&delivery_rate=0&cwnd=0&unsent_bytes=0&cid=2581445feac3607a&ts=721&x=0\"","timing-allow-origin":"*","vary":"Accept-Encoding","via":"ens-cache30.l2us4[160,160,206-0,M], ens-cache20.l2us4[161,0], ens-cache15.us22[0,0,200-0,H], ens-cache16.us22[5,0]","x-cache":"HIT TCP_HIT dirn:11:315619406 mlen:0","x-oss-cdn-auth":"success","x-oss-hash-crc64ecma":"16834050796546943518","x-oss-object-type":"Multipart","x-oss-request-id":"689C242CA5D3D93034286C85","x-oss-server-time":"8","x-oss-storage-class":"Standard","x-swift-cachetime":"31104000","x-swift-savetime":"Wed, 13 Aug 2025 05:35:40 GMT"}

View file

@ -0,0 +1 @@
{"accept-ranges":"bytes","access-control-allow-methods":"*","access-control-allow-origin":"https://xprime.tv","age":"199101","ali-swift-global-savetime":"1755054206","alt-svc":"h3=\":443\"; ma=86400","cache-control":"public, max-age=31536000, immutable","cdn-cache-control":"public, max-age=31536000, immutable","cf-cache-status":"MISS","cf-ray":"96f7f7937a70d26c-FRA","connection":"close","content-disposition":"attachment;filename=Alien: Earth-S1E1-1080P.mp4","content-length":"871281904","content-type":"video/mp4","date":"Fri, 15 Aug 2025 10:21:47 GMT","eagleid":"a3b5fea017552533074354078e","etag":"\"A916E682B7AC6E06B851A8C778FECF87-51\"","last-modified":"Wed, 13 Aug 2025 03:03:24 GMT","nel":"{\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}","report-to":"{\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=4VKbB%2B%2BCwOuVnc8rJR1AXcYR6yksEpmK1RNI5BXUt0EZW5HhZwtdvOVk%2BOdtenwt492cI5myJvdekV2GKA78Pz17V%2FMTLSCnaBXkfFKttbLfmdXxKL51w6dBncXMmq3J1rvW%2BlDBLMxqtMlvN%2FXNMlkJdZXScSc%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}","server":"cloudflare","server-timing":"cfL4;desc=\"?proto=TCP&rtt=0&min_rtt=0&rtt_var=0&sent=0&recv=0&lost=0&retrans=0&sent_bytes=0&recv_bytes=0&delivery_rate=0&cwnd=0&unsent_bytes=0&cid=eb4294c1b3c9cfec&ts=40&x=0\"","timing-allow-origin":"*","vary":"Accept-Encoding","via":"ens-cache12.l2de3[19,19,206-0,M], ens-cache2.l2de3[386,0], ens-cache5.de10[0,0,200-0,H], ens-cache12.de10[3,0]","x-cache":"HIT TCP_MEM_HIT dirn:-2:-2 mlen:0","x-oss-cdn-auth":"success","x-oss-hash-crc64ecma":"11633186024771853813","x-oss-object-type":"Multipart","x-oss-request-id":"689C007E989F153439D3D9E1","x-oss-server-time":"16","x-oss-storage-class":"Standard","x-swift-cachetime":"31104000","x-swift-savetime":"Wed, 13 Aug 2025 03:03:26 GMT"}

View file

@ -0,0 +1 @@
{"accept-ranges":"bytes","access-control-allow-methods":"*","access-control-allow-origin":"https://xprime.tv","age":"5442571","ali-swift-global-savetime":"1749810736","alt-svc":"h3=\":443\"; ma=86400","cache-control":"public, max-age=31536000, immutable","cdn-cache-control":"public, max-age=31536000, immutable","cf-cache-status":"MISS","cf-ray":"96f7f790ed31d26c-FRA","connection":"close","content-disposition":"attachment;filename=Superman.mp4","content-length":"896638128","content-type":"video/mp4","date":"Fri, 15 Aug 2025 10:21:47 GMT","eagleid":"a3b5fea317552533071221673e","etag":"\"E273E5E2EA0F4F351EE597E014D3EDEE-3\"","last-modified":"Thu, 01 Jun 2023 12:10:55 GMT","nel":"{\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}","report-to":"{\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=MPOgJvCX2NGVXvLVAkL9Do%2BXxQJB6Z2j1%2FaClvju88VXQvlO21PTiMZaPtnjIorRafTOREYJ9Y8892ZJkQ38oV5%2BNFcJSUfJQo8hY0Kv3rPPrNYWZBYMFGqgQhOxIk3dsBiowMrb22BRG6cgPv3UGjW4cCxuEoc%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}","server":"cloudflare","server-timing":"cfL4;desc=\"?proto=TCP&rtt=0&min_rtt=0&rtt_var=0&sent=0&recv=0&lost=0&retrans=0&sent_bytes=0&recv_bytes=0&delivery_rate=0&cwnd=0&unsent_bytes=0&cid=503c8ba5bfeda5bc&ts=125&x=0\"","timing-allow-origin":"*","vary":"Accept-Encoding","via":"ens-cache1.l2de3[0,0,206-0,H], ens-cache5.l2de3[1,0], ens-cache13.de10[0,0,200-0,H], ens-cache15.de10[4,0]","x-cache":"HIT TCP_MEM_HIT dirn:-2:-2 mlen:0","x-oss-cdn-auth":"success","x-oss-hash-crc64ecma":"4771098201880069728","x-oss-object-type":"Multipart","x-oss-qos-delay-time":"1426548","x-oss-request-id":"684BFE2F2547D43238F66A0F","x-oss-server-time":"4","x-oss-storage-class":"Standard","x-swift-cachetime":"30538308","x-swift-savetime":"Thu, 19 Jun 2025 23:40:28 GMT"}

View file

@ -0,0 +1 @@
{"accept-ranges":"bytes","access-control-allow-methods":"*","access-control-allow-origin":"https://xprime.tv","age":"1163","ali-swift-global-savetime":"1749411183","alt-svc":"h3=\":443\"; ma=86400","cache-control":"public, max-age=31536000, immutable","cdn-cache-control":"public, max-age=31536000, immutable","cf-cache-status":"HIT","cf-ray":"96f7f7909ca9d26c-FRA","connection":"close","content-disposition":"attachment;filename=Superman.mp4","content-length":"401394599","content-type":"video/mp4","date":"Fri, 15 Aug 2025 10:21:47 GMT","eagleid":"a3b5fea617552521434468697e","etag":"\"0F8C23B2BD3CC7F6BA6379E8354B0F84\"","last-modified":"Thu, 17 Nov 2022 00:30:11 GMT","nel":"{\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}","report-to":"{\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v4?s=5FtQGStEmGWQDt5%2FJ9tfbv6%2FV8Zu7qy7b%2BnLU%2BdVqv7ojoP7bEtRJ%2BXY5xpTmWTFuzFVroRhqPLEb873RCU60Jhc7iZhZDhLPISYsqnek%2BDvftzT96Fv9Yk1tQQxDL2pm%2BpAlnZfAD8D4cW%2BEQ4ofLszBL1YaTs%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}","server":"cloudflare","server-timing":"cfL4;desc=\"?proto=TCP&rtt=0&min_rtt=0&rtt_var=0&sent=0&recv=0&lost=0&retrans=0&sent_bytes=0&recv_bytes=0&delivery_rate=0&cwnd=0&unsent_bytes=0&cid=2e26c3ffa922ad37&ts=31&x=0\"","timing-allow-origin":"*","vary":"Accept-Encoding","via":"ens-cache8.l2de3[0,0,206-0,H], ens-cache12.l2de3[3,0], ens-cache17.de10[0,0,200-0,H], ens-cache18.de10[7,0]","x-cache":"HIT TCP_MEM_HIT dirn:-2:-2 mlen:0","x-oss-cdn-auth":"success","x-oss-hash-crc64ecma":"4264950399079041808","x-oss-object-type":"Normal","x-oss-request-id":"6845E56FB7AA223534E03B81","x-oss-server-time":"27","x-oss-storage-class":"Standard","x-swift-cachetime":"30691545","x-swift-savetime":"Fri, 13 Jun 2025 14:07:18 GMT"}

View file

@ -0,0 +1 @@
{"available_qualities":[],"has_subtitles":false,"message":"No exact match found for Jurassic World Rebirth (2025)","status":"not_found","streams":{},"subtitles":[]}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,87 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`XPrime primebox Alien: Earth 1`] = `
[
{
"format": "mp4",
"label": "XPrime Primebox",
"meta": {
"bytes": 871281904,
"countryCodes": [
"en",
],
"height": 1080,
"title": "Alien: Earth",
},
"requestHeaders": {
"Referer": "https://xprime.tv",
},
"sourceId": "xprime_en_primebox",
"ttl": 10800000,
"url": "https://oca.flutch09.workers.dev/?v=cenBDs9Hbnv6PuXYzNUtVR2ZZ2YtmVtQIt6JqHB1dsbz2Y%2BXC9UwPurnE%2BQNk27Yr1WeYeLOOazAnSL8cU0DvVfg4pwKsjHKWIJICiVlvv9ndXII0bR7eaIi%2B11NbAj72pFFryHZjO6MkMKEJJnF4G%2BH1BXIO1ALds7J1A7gj2vc7DbUWL8kPxwH1rMw7NAys20M5s3PsbhgSrMpguZSBm8X&headers=%7B%22origin%22%3A%22https%3A%2F%2Fmoviebox.ng%22%2C%22referer%22%3A%22https%3A%2F%2Fmoviebox.ng%22%7D&safe",
},
{
"format": "mp4",
"label": "XPrime Primebox",
"meta": {
"bytes": 420170402,
"countryCodes": [
"en",
],
"height": 480,
"title": "Alien: Earth",
},
"requestHeaders": {
"Referer": "https://xprime.tv",
},
"sourceId": "xprime_en_primebox",
"ttl": 10800000,
"url": "https://oca.flutch09.workers.dev/?v=oS2n5QbXtpa%2BWXMpIIi0SqeqadEyYEAg6AmHvpTa3jzooh6zxINciUJrR%2B6b1xLZtxbnbAM3mrGGXOa5yckYkNSC%2BKGEFSdofXw298vq3ssHpI9LBN6XLvhtxnDfmub0QoMG%2Fkvgjhb8T%2FwiCHo9NeSX%2FetW6ANppW9jhZn0Hv3hsWdmES1jqj6nfIjQ1ur53htjr2vF7mZbZSsJ&headers=%7B%22origin%22%3A%22https%3A%2F%2Fmoviebox.ng%22%2C%22referer%22%3A%22https%3A%2F%2Fmoviebox.ng%22%7D&safe",
},
]
`;
exports[`XPrime primebox Superman 1`] = `
[
{
"format": "mp4",
"label": "XPrime Primebox",
"meta": {
"bytes": 401394599,
"countryCodes": [
"en",
],
"height": 480,
"title": "Superman (2025)",
},
"requestHeaders": {
"Referer": "https://xprime.tv",
},
"sourceId": "xprime_en_primebox",
"ttl": 10800000,
"url": "https://oca.flutch09.workers.dev/?v=3RVZDNxcKNs6%2BqcdL1bDCgq9Yp1iPYqb6a9yToLq66vlzu08R1Hz7jiKx4OBH6YzJBcK7skuiDGDwIpro78ReVjMLtMHCfa0fBo0aJ9RYULOUMkLrZxjzSTXvo5Jss1Jiss8e9Z8pFdlC1VqwAUm6G9mx0u41dFLJ0GTJrwCesPe4zflbL8I76WkWYKBMT2MwHvDTIO4r3V0nf8BsRswsNJZ&headers=%7B%22origin%22%3A%22https%3A%2F%2Fmoviebox.ng%22%2C%22referer%22%3A%22https%3A%2F%2Fmoviebox.ng%22%7D&safe",
},
{
"format": "mp4",
"label": "XPrime Primebox",
"meta": {
"bytes": 896638128,
"countryCodes": [
"en",
],
"height": 720,
"title": "Superman (2025)",
},
"requestHeaders": {
"Referer": "https://xprime.tv",
},
"sourceId": "xprime_en_primebox",
"ttl": 10800000,
"url": "https://oca.flutch09.workers.dev/?v=gUbhHOwpFIqajH6NnoH%2BYE9AWORUUogamkdYQedBfKi5eQtyniWtxmI1%2B5Swyl1ThC6vM0qHl53s0Q7j%2BDaWFhVRJQL%2BJRxbuOL1iCz1w5xVPLDU%2FTJ3zhf9EbULPGbbee14kdNYNc5%2FlF2sNe6RiUupsvhlj%2BjcgsT8uypX%2BudVyw1jVEUVogufPnc0lSrfoE98IZlOgdjBZKE3%2Fcw3erD2&headers=%7B%22origin%22%3A%22https%3A%2F%2Fmoviebox.ng%22%2C%22referer%22%3A%22https%3A%2F%2Fmoviebox.ng%22%7D&safe",
},
]
`;
exports[`XPrime primebox not found 1`] = `[]`;
exports[`XPrime unknown backend is ignored 1`] = `[]`;

View file

@ -14,6 +14,7 @@ import { SuperVideo } from './SuperVideo';
import { Uqload } from './Uqload';
import { VidSrc } from './VidSrc';
import { VixSrc } from './VixSrc';
import { XPrime } from './XPrime';
export * from './Extractor';
export * from './ExtractorRegistry';
@ -32,5 +33,6 @@ export const createExtractors = (fetcher: Fetcher): Extractor[] => [
new Uqload(fetcher),
new VidSrc(fetcher, ['in', 'pm', 'net', 'xyz', 'io', 'vc']), // https://vidsrc.domains/
new VixSrc(fetcher),
new XPrime(fetcher),
new ExternalUrl(fetcher), // fallback extractor which must come last
];

23
src/source/XPrime.test.ts Normal file
View file

@ -0,0 +1,23 @@
import { createTestContext } from '../test';
import { FetcherMock, TmdbId } from '../utils';
import { XPrime } from './XPrime';
const ctx = createTestContext();
describe('XPrime', () => {
let handler: XPrime;
beforeEach(() => {
handler = new XPrime(new FetcherMock(`${__dirname}/__fixtures__/XPrime`));
});
test('handle alien: earth 1x1', async () => {
const streams = await handler.handle(ctx, 'series', new TmdbId(157239, 1, 1));
expect(streams).toMatchSnapshot();
});
test('handle superman', async () => {
const streams = await handler.handle(ctx, 'series', new TmdbId(1061474, undefined, undefined));
expect(streams).toMatchSnapshot();
});
});

42
src/source/XPrime.ts Normal file
View file

@ -0,0 +1,42 @@
import { ContentType } from 'stremio-addon-sdk';
import { Context, CountryCode } from '../types';
import { Fetcher, getTmdbId, getTmdbNameAndYear, Id } from '../utils';
import { Source, SourceResult } from './types';
export class XPrime implements Source {
public readonly id = 'xprime';
public readonly label = 'XPrime';
public readonly contentTypes: ContentType[] = ['movie', 'series'];
public readonly countryCodes: CountryCode[] = [CountryCode.en];
public readonly baseUrl = 'https://backend.xprime.tv';
private readonly fetcher: Fetcher;
public constructor(fetcher: Fetcher) {
this.fetcher = fetcher;
}
public async handle(ctx: Context, _type: string, id: Id): Promise<SourceResult[]> {
const tmdbId = await getTmdbId(ctx, this.fetcher, id);
const [name, year] = await getTmdbNameAndYear(ctx, this.fetcher, tmdbId);
if (tmdbId.season) {
const title = `${name} ${tmdbId.season}x${tmdbId.episode}`;
const urlPrimebox = new URL(`/primebox?name=${encodeURIComponent(name)}&year=${year}&season=${tmdbId.season}&episode=${tmdbId.episode}`, this.baseUrl);
return [{ countryCode: CountryCode.en, title, url: urlPrimebox }];
}
const title = `${name} (${year})`;
const urlPrimebox = new URL(`/primebox?name=${encodeURIComponent(name)}&year=${year}`, this.baseUrl);
return [{ countryCode: CountryCode.en, title, url: urlPrimebox }];
};
}

View file

@ -0,0 +1 @@
{"adult":false,"backdrop_path":"/eU7IfdWq8KQy0oNd4kKXS0QUR08.jpg","belongs_to_collection":null,"budget":225000000,"genres":[{"id":878,"name":"Science Fiction"},{"id":12,"name":"Adventure"},{"id":28,"name":"Action"}],"homepage":"https://www.superman.com","id":1061474,"imdb_id":"tt5950044","origin_country":["US"],"original_language":"en","original_title":"Superman","overview":"Superman, a journalist in Metropolis, embarks on a journey to reconcile his Kryptonian heritage with his human upbringing as Clark Kent.","popularity":168.8676,"poster_path":"/ombsmhYUqR4qqOLOxAyr5V8hbyv.jpg","production_companies":[{"id":184898,"logo_path":"/2Z2hiM1ERqFOWRxNxWoJZ8lTxhb.png","name":"DC Studios","origin_country":"US"},{"id":94218,"logo_path":"/kxuhS8wyKtVprOn5nckdHyNuSg1.png","name":"Troll Court Entertainment","origin_country":"US"},{"id":11565,"logo_path":"/odU3l6csuBmXUrzFm6araUgEUHQ.png","name":"The Safran Company","origin_country":"US"},{"id":216687,"logo_path":"/kKVYqekveOvLK1IgqdJojLjQvtu.png","name":"Domain Entertainment","origin_country":"US"}],"production_countries":[{"iso_3166_1":"US","name":"United States of America"}],"release_date":"2025-07-09","revenue":581086143,"runtime":130,"spoken_languages":[{"english_name":"English","iso_639_1":"en","name":"English"}],"status":"Released","tagline":"Look up.","title":"Superman","video":false,"vote_average":7.7,"vote_count":1684}

View file

@ -0,0 +1 @@
{"adult":false,"backdrop_path":"/25g7mthXoJFcNZhAKz0evk17Bsx.jpg","created_by":[{"id":202816,"credit_id":"620bdfc73e01ea002b2f90b1","name":"Noah Hawley","original_name":"Noah Hawley","gender":2,"profile_path":"/pxVP1lywEBA9y8x5Xe3kM7m4ai3.jpg"}],"episode_run_time":[],"first_air_date":"2025-08-12","genres":[{"id":10765,"name":"Sci-Fi & Fantasy"},{"id":18,"name":"Drama"}],"homepage":"https://www.fxnetworks.com/shows/alien-earth","id":157239,"in_production":true,"languages":["en"],"last_air_date":"2025-08-12","last_episode_to_air":{"id":6231083,"name":"Mr. October","overview":"Tensions rise between rival corporations, a reunion takes place, and a secret is revealed.","vote_average":8.5,"vote_count":10,"air_date":"2025-08-12","episode_number":2,"episode_type":"standard","production_code":"XWYV1002","runtime":56,"season_number":1,"show_id":157239,"still_path":"/hZclNGZx4pjOx6MNdJfTZid113f.jpg"},"name":"Alien: Earth","next_episode_to_air":{"id":6231084,"name":"Metamorphosis","overview":"The team returns home with unexpected cargo. An unsettling experiment occurs, and a new talent is discovered.","vote_average":0.0,"vote_count":0,"air_date":"2025-08-19","episode_number":3,"episode_type":"standard","production_code":"","runtime":54,"season_number":1,"show_id":157239,"still_path":null},"networks":[{"id":88,"logo_path":"/aexGjtcs42DgRtZh7zOxayiry4J.png","name":"FX","origin_country":"US"},{"id":453,"logo_path":"/pqUTCleNUiTLAVlelGxUgWn1ELh.png","name":"Hulu","origin_country":"US"}],"number_of_episodes":8,"number_of_seasons":1,"origin_country":["US"],"original_language":"en","original_name":"Alien: Earth","overview":"When the mysterious deep space research vessel USCSS Maginot crash-lands on Earth, Wendy and a ragtag group of tactical soldiers make a fateful discovery that puts them face-to-face with the planet's greatest threat.","popularity":395.6075,"poster_path":"/yueXS3q8BtoWekcHOATFHicLl3e.jpg","production_companies":[{"id":15990,"logo_path":"/5cT4zwHA66uNAr2p3CcBDLddXu2.png","name":"FX Productions","origin_country":"US"},{"id":221347,"logo_path":"/6Ry6uNBaa0IbbSs1XYIgX5DkA9r.png","name":"Scott Free Productions","origin_country":"US"},{"id":20814,"logo_path":null,"name":"26 Keys Productions","origin_country":"US"}],"production_countries":[{"iso_3166_1":"US","name":"United States of America"}],"seasons":[{"air_date":null,"episode_count":2,"id":469846,"name":"Specials","overview":"","poster_path":null,"season_number":0,"vote_average":0.0},{"air_date":"2025-08-12","episode_count":8,"id":243129,"name":"Season 1","overview":"As members of the crash recovery crew search for survivors among the wreckage of a mysterious crashed space vessel, they encounter mysterious predatory life forms more terrifying than they could have ever imagined.With this new threat unlocked, the search crew must fight for survival and what they choose to do with this discovery could change planet Earth as they know it.","poster_path":"/dJ7lUdzZ98AlhZ38BpfG6jy3UDa.jpg","season_number":1,"vote_average":8.3}],"spoken_languages":[{"english_name":"English","iso_639_1":"en","name":"English"}],"status":"Returning Series","tagline":"We were safer in space.","type":"Scripted","vote_average":8.26,"vote_count":96}

View file

@ -0,0 +1,21 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
exports[`XPrime handle alien: earth 1x1 1`] = `
[
{
"countryCode": "en",
"title": "Alien: Earth 1x1",
"url": "https://backend.xprime.tv/primebox?name=Alien%3A%20Earth&year=2025&season=1&episode=1",
},
]
`;
exports[`XPrime handle superman 1`] = `
[
{
"countryCode": "en",
"title": "Superman (2025)",
"url": "https://backend.xprime.tv/primebox?name=Superman&year=2025",
},
]
`;

View file

@ -16,6 +16,7 @@ import { Source } from './types';
import { VerHdLink } from './VerHdLink';
import { VidSrc } from './VidSrc';
import { VixSrc } from './VixSrc';
import { XPrime } from './XPrime';
export * from './types';
@ -26,6 +27,7 @@ export const createSources = (fetcher: Fetcher): Source[] => [
new PrimeWire(fetcher),
new Soaper(fetcher),
new VidSrc(fetcher),
new XPrime(fetcher),
// ES / MX
new CineHDPlus(fetcher),
new Cuevana(fetcher),

View file

@ -21,7 +21,7 @@ exports[`buildManifest default manifest 1`] = `
},
{
"key": "en",
"title": "English 🇺🇸 (PrimeWire, Soaper, VidSrc, VixSrc)",
"title": "English 🇺🇸 (PrimeWire, Soaper, VidSrc, VixSrc, XPrime)",
"type": "checkbox",
},
{