@vyla-entertainment/sdk 1.20.0 → 1.22.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 (58) hide show
  1. package/package.json +3 -2
  2. package/src/config.js +99 -67
  3. package/src/health.js +60 -20
  4. package/src/sdk.d.ts +94 -121
  5. package/src/sdk.js +82 -78
  6. package/src/sources/111477.js +88 -100
  7. package/src/sources/123anime.js +120 -56
  8. package/src/sources/3eyedraven.js +82 -135
  9. package/src/sources/4movies.js +77 -0
  10. package/src/sources/aether.js +99 -0
  11. package/src/sources/castle.js +415 -0
  12. package/src/sources/cinecat.js +37 -18
  13. package/src/sources/cinemaarmy.js +179 -180
  14. package/src/sources/cinesrc.js +401 -397
  15. package/src/sources/cno.js +101 -94
  16. package/src/sources/dulo.js +134 -149
  17. package/src/sources/flaxmovies.js +114 -105
  18. package/src/sources/framextv.js +126 -0
  19. package/src/sources/frost.js +38 -29
  20. package/src/sources/fsonline.js +95 -47
  21. package/src/sources/hdhub.js +43 -36
  22. package/src/sources/hexa.js +60 -53
  23. package/src/sources/hyper.js +42 -35
  24. package/src/sources/kickassanime.js +117 -124
  25. package/src/sources/kisskh.js +114 -59
  26. package/src/sources/lmscript.js +72 -70
  27. package/src/sources/lookmovie.js +80 -79
  28. package/src/sources/meowtv.js +140 -0
  29. package/src/sources/movenerds.js +74 -124
  30. package/src/sources/movy.js +197 -209
  31. package/src/sources/net79.js +59 -55
  32. package/src/sources/peestream.js +126 -138
  33. package/src/sources/pengu.js +46 -49
  34. package/src/sources/pstream.js +73 -67
  35. package/src/sources/purstream.js +96 -104
  36. package/src/sources/rivestream.js +182 -176
  37. package/src/sources/rivo.js +58 -53
  38. package/src/sources/streamaggregator.js +114 -128
  39. package/src/sources/thugtv.js +70 -62
  40. package/src/sources/vidapi.js +122 -114
  41. package/src/sources/vidcore.js +14 -122
  42. package/src/sources/vidfast.js +14 -122
  43. package/src/sources/vidlink.js +78 -27
  44. package/src/sources/vidora.js +74 -42
  45. package/src/sources/vidup.js +14 -122
  46. package/src/sources/vidvault.js +133 -187
  47. package/src/sources/vidy.js +192 -187
  48. package/src/sources/vidzee.js +189 -183
  49. package/src/sources/vixsrc.js +123 -113
  50. package/src/sources/watchout.js +60 -46
  51. package/src/sources/xdownloader.js +127 -128
  52. package/src/sources/yapgrid.js +68 -62
  53. package/src/sources/yastream.js +35 -29
  54. package/src/subtitles.js +105 -122
  55. package/src/utils/helpers.js +586 -247
  56. package/src/sources/bcine.js +0 -202
  57. package/src/sources/cinezo.js +0 -55
  58. package/src/sources/vidrock.js +0 -145
@@ -1,136 +1,83 @@
1
- import { getUA } from "../utils/helpers.js";
2
-
3
- const BASE_URL = "https://3eyedraven.watch";
4
- const API_BASE = "https://3eyedraven.watch/api";
5
-
6
- function getHeaders() {
7
- return {
8
- "User-Agent": getUA(),
9
- Accept: "application/json",
10
- Referer: `${BASE_URL}/`,
11
- Origin: BASE_URL,
12
- };
13
- }
14
-
15
- function resolveApiKey(args) {
16
- return (
17
- args?.tmdbApiKey ||
18
- args?.sdk?.tmdbApiKey ||
19
- process.env.TMDB_API_KEY ||
20
- null
21
- );
22
- }
23
-
24
- async function getTitle(id, isTv, apiKey) {
25
- if (!apiKey) return null;
26
- const type = isTv ? "tv" : "movie";
27
- try {
28
- const res = await fetch(
29
- `https://api.themoviedb.org/3/${type}/${id}?api_key=${apiKey}`,
30
- { signal: AbortSignal.timeout(5000) }
31
- );
32
- if (!res.ok) return null;
33
- const data = await res.json();
34
- return isTv ? data.name : data.title;
35
- } catch {
36
- return null;
37
- }
38
- }
39
-
40
- function slugify(text) {
41
- return text
42
- .toLowerCase()
43
- .normalize("NFKD")
44
- .replace(/[\u0300-\u036f]/g, "")
45
- .replace(/[^a-z0-9]+/g, "-")
46
- .replace(/^-|-$/g, "");
47
- }
48
-
49
- function absolute(url) {
50
- if (!url) return "";
51
- if (/^https?:\/\//.test(url)) return url;
52
- return `${BASE_URL}${url.startsWith("/") ? "" : "/"}${url}`;
53
- }
54
-
55
- export async function getStream(args) {
56
- const { id, s = null, e = null } = args;
57
- const isTv = s != null && e != null;
58
-
59
- const apiKey = resolveApiKey(args);
60
- const title = await getTitle(id, isTv, apiKey);
61
-
62
- if (!title) {
63
- if (process.env.DEBUG_CAUSE) {
64
- console.error(
65
- `[3eyedraven] Could not resolve title for ${isTv ? "tv" : "movie"} ${id} ` +
66
- `(tmdbApiKey ${apiKey ? "present" : "MISSING"})`
67
- );
68
- }
69
- return null;
70
- }
71
-
72
- const identifier = `${slugify(title)}-${id}`;
73
-
74
- const url = isTv
75
- ? `${API_BASE}/stream/${identifier}?season=${s}&episode=${e}`
76
- : `${API_BASE}/stream/${identifier}`;
77
-
78
- try {
79
- const res = await fetch(url, {
80
- headers: getHeaders(),
81
- signal: AbortSignal.timeout(15000),
82
- });
83
-
84
- if (!res.ok) {
85
- if (process.env.DEBUG_CAUSE) {
86
- console.error(`[3eyedraven] HTTP ${res.status} for ${url}`);
87
- }
88
- return null;
89
- }
90
-
91
- const data = await res.json();
92
- const stream = data?.stream;
93
- if (!stream?.url) {
94
- if (process.env.DEBUG_CAUSE) {
95
- console.error(`[3eyedraven] No stream.url in response for ${url}`);
96
- }
97
- return null;
98
- }
99
-
100
- const streamUrl = absolute(stream.url);
101
- if (!/^https?:\/\//.test(streamUrl)) return null;
102
-
103
- const subtitles = (stream.subtitles || [])
104
- .map(sub => {
105
- const subUrl = absolute(sub.url);
106
- if (!subUrl) return null;
107
- return {
108
- label: sub.label || sub.language || "Subtitle",
109
- file: subUrl,
110
- type: "vtt",
111
- source: "3eyedraven",
112
- };
113
- })
114
- .filter(Boolean);
115
-
116
- return {
117
- url: streamUrl,
118
- headers: {
119
- "User-Agent": getUA(),
120
- Referer: `${BASE_URL}/`,
121
- Origin: BASE_URL,
122
- },
123
- server: "3eyedraven",
124
- quality: "1080p",
125
- type: stream.format === "hls" ? "hls" : "mp4",
126
- subtitles,
127
- skipProxy: true,
128
- };
129
- } catch (err) {
130
- if (process.env.DEBUG_CAUSE) {
131
- console.error(`[3eyedraven] fetch error for ${url}:`, err.message);
132
- if (err.cause) console.error(" cause:", err.cause.code, err.cause.message);
133
- }
134
- return null;
135
- }
1
+ import { getTmdbMetadata, getUA, resolveTmdbKey, slugify } from '../utils/helpers.js';
2
+
3
+ const BASE_URL = 'https://3eyedraven.watch';
4
+ const API_BASE = 'https://3eyedraven.watch/api';
5
+
6
+ function absolute(url) {
7
+ if (!url) return '';
8
+ if (/^https?:\/\//.test(url)) return url;
9
+ return `${BASE_URL}${url.startsWith('/') ? '' : '/'}${url}`;
10
+ }
11
+
12
+ export async function getStream(args) {
13
+ const { id, s, e, sdk } = args || {};
14
+ const isTv = s != null && e != null;
15
+ const apiKey = resolveTmdbKey(args, sdk);
16
+
17
+ const meta = await getTmdbMetadata(id, isTv, apiKey);
18
+ const title = meta?.title;
19
+ if (!title) return null;
20
+
21
+ const identifier = `${slugify(title)}-${id}`;
22
+ const url = isTv
23
+ ? `${API_BASE}/stream/${identifier}?season=${s}&episode=${e}`
24
+ : `${API_BASE}/stream/${identifier}`;
25
+
26
+ const headers = {
27
+ 'User-Agent': getUA(),
28
+ Accept: 'application/json',
29
+ Referer: `${BASE_URL}/`,
30
+ Origin: BASE_URL,
31
+ };
32
+
33
+ try {
34
+ const res = await fetch(url, {
35
+ headers,
36
+ signal: AbortSignal.timeout(15000),
37
+ });
38
+ if (!res.ok) return null;
39
+
40
+ const data = await res.json();
41
+ const stream = data?.stream;
42
+ if (!stream?.url) return null;
43
+
44
+ const streamUrl = absolute(stream.url);
45
+ if (!/^https?:\/\//.test(streamUrl)) return null;
46
+
47
+ const subtitles = (stream.subtitles || [])
48
+ .map(sub => {
49
+ const subUrl = absolute(sub.url);
50
+ if (!subUrl) return null;
51
+ return {
52
+ label: sub.label || sub.language || 'Subtitle',
53
+ file: subUrl,
54
+ type: 'vtt',
55
+ source: '3eyedraven',
56
+ };
57
+ })
58
+ .filter(Boolean);
59
+
60
+ const allUrls = [{
61
+ url: streamUrl,
62
+ headers,
63
+ server: '3eyedraven',
64
+ quality: '1080p',
65
+ type: stream.format === 'hls' ? 'hls' : 'mp4',
66
+ subtitles,
67
+ skipProxy: true,
68
+ }];
69
+
70
+ return {
71
+ url: streamUrl,
72
+ headers,
73
+ server: '3eyedraven',
74
+ quality: '1080p',
75
+ type: stream.format === 'hls' ? 'hls' : 'mp4',
76
+ subtitles,
77
+ skipProxy: true,
78
+ allUrls,
79
+ };
80
+ } catch {
81
+ return null;
82
+ }
136
83
  }
@@ -0,0 +1,77 @@
1
+ const BASE_URL = 'https://4movie.in';
2
+ const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36';
3
+
4
+ const HEADERS = {
5
+ 'User-Agent': UA,
6
+ Referer: `${BASE_URL}/`,
7
+ Origin: BASE_URL,
8
+ Accept: 'application/json, text/plain, */*',
9
+ 'Accept-Language': 'en-US,en;q=0.9',
10
+ };
11
+
12
+ const PLAYBACK_HEADERS = {
13
+ 'User-Agent': UA,
14
+ Referer: `${BASE_URL}/`,
15
+ Origin: BASE_URL,
16
+ };
17
+
18
+ export async function getStream(args) {
19
+ const { id, s, e } = args || {};
20
+ const isTv = s != null && e != null;
21
+
22
+ let query = isTv
23
+ ? `tmdb=${id}&type=tv&season=${s}&episode=${e}`
24
+ : `tmdb=${id}&type=movie`;
25
+
26
+ if (args?.title) query += `&title=${encodeURIComponent(args.title)}`;
27
+ if (args?.year) query += `&year=${encodeURIComponent(args.year)}`;
28
+
29
+ const targetUrl = `${BASE_URL}/api/hubcloud?${query}`;
30
+
31
+ const res = await fetch(targetUrl, { headers: HEADERS }).catch(() => null);
32
+ if (!res || !res.ok) return null;
33
+
34
+ const data = await res.json().catch(() => null);
35
+ if (!data?.ok || !Array.isArray(data.streams) || !data.streams.length) return null;
36
+
37
+ const allUrls = [];
38
+ const seen = new Set();
39
+
40
+ for (const stream of data.streams) {
41
+ if (stream.rawUrl && !seen.has(stream.rawUrl)) {
42
+ seen.add(stream.rawUrl);
43
+ allUrls.push({
44
+ url: stream.rawUrl,
45
+ server: `4Movies - ${stream.name || 'Direct'}`,
46
+ quality: stream.quality || 'Auto',
47
+ type: stream.type || (stream.rawUrl.includes('.m3u8') ? 'hls' : 'mp4'),
48
+ headers: PLAYBACK_HEADERS,
49
+ });
50
+ }
51
+
52
+ if (stream.url) {
53
+ const proxyUrl = stream.url.startsWith('http')
54
+ ? stream.url
55
+ : `${BASE_URL}${stream.url.startsWith('/') ? '' : '/'}${stream.url}`;
56
+
57
+ if (!seen.has(proxyUrl)) {
58
+ seen.add(proxyUrl);
59
+ allUrls.push({
60
+ url: proxyUrl,
61
+ server: `4Movies - ${stream.name ? `${stream.name} (Proxy)` : 'Proxy'}`,
62
+ quality: stream.quality || 'Auto',
63
+ type: stream.type || 'hls',
64
+ headers: PLAYBACK_HEADERS,
65
+ });
66
+ }
67
+ }
68
+ }
69
+
70
+ if (!allUrls.length) return null;
71
+
72
+ return {
73
+ url: allUrls[0].url,
74
+ headers: allUrls[0].headers,
75
+ allUrls,
76
+ };
77
+ }
@@ -0,0 +1,99 @@
1
+ const UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36';
2
+
3
+ const HEADERS = {
4
+ 'User-Agent': UA,
5
+ Origin: 'https://aether.st',
6
+ Referer: 'https://aether.st/',
7
+ Accept: 'application/json, text/plain, */*',
8
+ 'Accept-Language': 'en-US,en;q=0.9',
9
+ };
10
+
11
+ const PLAYBACK_HEADERS = {
12
+ 'User-Agent': UA,
13
+ Referer: 'https://aether.st/',
14
+ Origin: 'https://aether.st',
15
+ };
16
+
17
+ function extractStreamUrls(data, target) {
18
+ const urls = [];
19
+ if (!data) return urls;
20
+
21
+ if (Array.isArray(data.streams)) {
22
+ for (const s of data.streams) {
23
+ if (s?.url) {
24
+ urls.push({
25
+ url: s.url,
26
+ name: `${target.name} (${s.name || s.language || 'Default'})`,
27
+ quality: s.quality || 'Auto',
28
+ type: s.type || (s.url.includes('.m3u8') ? 'hls' : 'mp4'),
29
+ });
30
+ }
31
+ }
32
+ }
33
+
34
+ const singleUrl = data.directUrl || data.url || data.stream;
35
+ if (typeof singleUrl === 'string' && /^https?:\/\//.test(singleUrl)) {
36
+ urls.push({
37
+ url: singleUrl,
38
+ name: `${target.name}${data.server ? ` - ${data.server}` : ''}`,
39
+ quality: data.quality || 'Auto',
40
+ type: data.streamType || data.container || (singleUrl.includes('.m3u8') ? 'hls' : 'mp4'),
41
+ });
42
+ }
43
+
44
+ return urls;
45
+ }
46
+
47
+ export async function getStream(args) {
48
+ const { id, s, e } = args || {};
49
+ const isTv = s != null && e != null;
50
+
51
+ const endpoints = [
52
+ { name: 'Meridian', url: isTv ? `https://meridian.raccoonunbutteredbagel.zip/show/${id}/${s}/${e}` : `https://meridian.raccoonunbutteredbagel.zip/movie/${id}` },
53
+ { name: 'Rock', url: isTv ? `https://rock.raccoonunbutteredbagel.zip/tv/${id}/${s}/${e}` : `https://rock.raccoonunbutteredbagel.zip/movie/${id}` },
54
+ { name: 'Shore', url: isTv ? `https://shore.raccoonunbutteredbagel.zip/show/${id}?s=${s}&e=${e}` : `https://shore.raccoonunbutteredbagel.zip/movie/${id}` },
55
+ { name: 'Filler', url: isTv ? `https://filler.raccoonunbutteredbagel.zip/tv/${id}/${s}/${e}` : `https://filler.raccoonunbutteredbagel.zip/movie/${id}` },
56
+ { name: 'Tiki', url: isTv ? `https://tiki.raccoonunbutteredbagel.zip/tv/${id}/${s}/${e}` : `https://tiki.raccoonunbutteredbagel.zip/movie/${id}` },
57
+ { name: 'Link', url: isTv ? `https://link.raccoonunbutteredbagel.zip/tv/${id}/${s}/${e}` : `https://link.raccoonunbutteredbagel.zip/movie/${id}` },
58
+ { name: 'VFast Rapid', url: isTv ? `https://vfast.raccoonunbutteredbagel.zip/tv/${id}/${s}/${e}?server=vRapid` : `https://vfast.raccoonunbutteredbagel.zip/movie/${id}?server=vRapid` },
59
+ { name: 'VFast Blaze', url: isTv ? `https://vfast.raccoonunbutteredbagel.zip/tv/${id}/${s}/${e}?server=vBlaze` : `https://vfast.raccoonunbutteredbagel.zip/movie/${id}?server=vBlaze` },
60
+ ];
61
+
62
+ const responses = await Promise.allSettled(
63
+ endpoints.map(async target => {
64
+ const res = await fetch(target.url, { headers: HEADERS });
65
+ if (!res.ok) return null;
66
+ const data = await res.json();
67
+ return { target, data };
68
+ })
69
+ );
70
+
71
+ const allUrls = [];
72
+ const seen = new Set();
73
+
74
+ for (const res of responses) {
75
+ if (res.status !== 'fulfilled' || !res.value?.data) continue;
76
+ const { target, data } = res.value;
77
+ const found = extractStreamUrls(data, target);
78
+
79
+ for (const item of found) {
80
+ if (!item?.url || seen.has(item.url)) continue;
81
+ seen.add(item.url);
82
+ allUrls.push({
83
+ url: item.url,
84
+ server: `Aether - ${item.name}`,
85
+ quality: item.quality || 'Auto',
86
+ type: item.type || (item.url.includes('.m3u8') ? 'hls' : 'mp4'),
87
+ headers: PLAYBACK_HEADERS,
88
+ });
89
+ }
90
+ }
91
+
92
+ if (!allUrls.length) return null;
93
+
94
+ return {
95
+ url: allUrls[0].url,
96
+ headers: allUrls[0].headers,
97
+ allUrls,
98
+ };
99
+ }