skystream-cli 1.4.5 → 1.4.7

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 (2) hide show
  1. package/dist/index.js +55 -45
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ const program = new Command();
12
12
  program
13
13
  .name('skystream')
14
14
  .description('SkyStream Plugin Development Kit CLI (Sky Gen 2)')
15
- .version('1.4.4');
15
+ .version('1.4.7');
16
16
  // Schemas
17
17
  const pluginSchema = z.object({
18
18
  packageName: z.string().min(5).regex(/^[a-z0-9._-]+$/),
@@ -163,7 +163,13 @@ const JS_TEMPLATE = `(function() {
163
163
  ],
164
164
  nextAiring: new NextAiring({ episode: 5, season: 1, airDate: "2024-04-01" }),
165
165
  recommendations: [
166
- new MultimediaItem({ title: "Similar Show", url: \`\${manifest.baseUrl}/similar\`, posterUrl: "...", type: "series" })
166
+ new MultimediaItem({ title: "Similar Show", url: \`\${manifest.baseUrl}/similar\`, posterUrl: "https://placehold.co/400x600", type: "series" })
167
+ ],
168
+ playbackPolicy: "none", // 'none' | 'VPN Recommended' | 'torrent' | 'externalPlayerOnly' | 'internalPlayerOnly'
169
+ syncData: { "my_service_id": "12345" }, // Optional: external metadata sync
170
+ streams: [
171
+ // Optional: "Instant Load" - bypass loadStreams by providing links here
172
+ new StreamResult({ url: "https://example.com/movie.mp4", source: "Instant High" })
167
173
  ],
168
174
  headers: { "Referer": \`\${manifest.baseUrl}\` },
169
175
  episodes: [
@@ -174,7 +180,8 @@ const JS_TEMPLATE = `(function() {
174
180
  episode: 1,
175
181
  description: "Episode summary...",
176
182
  posterUrl: \`https://placehold.co/400x600.png?text=Episode+Poster\`,
177
- headers: { "Referer": \`\${manifest.baseUrl}\` }
183
+ headers: { "Referer": \`\${manifest.baseUrl}\` },
184
+ streams: [] // Optional: "Instant Load" for episodes
178
185
  }),
179
186
  new Episode({
180
187
  name: "Episode 2",
@@ -200,25 +207,19 @@ const JS_TEMPLATE = `(function() {
200
207
  */
201
208
  async function loadStreams(url, cb) {
202
209
  try {
203
- // Standard: Return a List of stream urls
210
+ // Standard: Return a List of stream objects
204
211
  cb({
205
212
  success: true,
206
213
  data: [
207
214
  new StreamResult({
208
215
  url: "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8",
209
- source: "Server [1080p]", // (optional)
210
- headers: { "Referer": \`\${manifest.baseUrl}\` }, // (optional)
211
- subtitles: [
212
- { url: \`\${manifest.baseUrl}/sub.vtt\`, label: "English", lang: "en" } // (optional)
213
- ],
214
- drmKid: "kid_value", // (optional)
215
- drmKey: "key_value", // (optional)
216
- licenseUrl: "https://license-server.com" // (optional)
216
+ source: "Direct Quality",
217
+ headers: { "Referer": \`\${manifest.baseUrl}\` }
217
218
  })
218
219
  ]
219
220
  });
220
221
  } catch (e) {
221
- cb({ success: false, errorCode: "STREAM_ERROR", message: (e instanceof Error) ? e.message : String(e) });
222
+ cb({ success: false, errorCode: "STREAM_ERROR", message: String(e) });
222
223
  }
223
224
  }
224
225
 
@@ -447,6 +448,7 @@ program.command('test')
447
448
  const manifest = await fs.readJson(manifestPath);
448
449
  const jsContent = await fs.readFile(jsPath, 'utf8');
449
450
  console.log(`\n--- Testing ${manifest.packageName} -> ${options.function} ---`);
451
+ const preferences = {};
450
452
  const context = {
451
453
  manifest,
452
454
  console: {
@@ -455,11 +457,16 @@ program.command('test')
455
457
  },
456
458
  http_get: async (url, headers, cb) => {
457
459
  try {
458
- const res = await axios.get(url, { headers: headers || {} });
459
- const result = { status: res.status, statusCode: res.status, body: typeof res.data === 'string' ? res.data : JSON.stringify(res.data), headers: res.headers };
460
+ const finalHeaders = { ...(headers || {}) };
461
+ if (!Object.keys(finalHeaders).some(k => k.toLowerCase() === 'user-agent')) {
462
+ finalHeaders['User-Agent'] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36";
463
+ }
464
+ const res = await axios.get(url, { headers: finalHeaders });
465
+ const body = typeof res.data === 'string' ? res.data : JSON.stringify(res.data);
466
+ const response = { status: res.status, statusCode: res.status, body, headers: res.headers };
460
467
  if (cb)
461
- cb(result);
462
- return result;
468
+ cb(response);
469
+ return response;
463
470
  }
464
471
  catch (e) {
465
472
  const res = { status: e.response?.status || 500, statusCode: e.response?.status || 500, body: e.response?.data || e.message, headers: e.response?.headers || {} };
@@ -470,11 +477,16 @@ program.command('test')
470
477
  },
471
478
  http_post: async (url, headers, body, cb) => {
472
479
  try {
473
- const res = await axios.post(url, body, { headers: headers || {} });
474
- const result = { status: res.status, statusCode: res.status, body: typeof res.data === 'string' ? res.data : JSON.stringify(res.data), headers: res.headers };
480
+ const finalHeaders = { ...(headers || {}) };
481
+ if (!Object.keys(finalHeaders).some(k => k.toLowerCase() === 'user-agent')) {
482
+ finalHeaders['User-Agent'] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36";
483
+ }
484
+ const res = await axios.post(url, body, { headers: finalHeaders });
485
+ const resBody = typeof res.data === 'string' ? res.data : JSON.stringify(res.data);
486
+ const response = { status: res.status, statusCode: res.status, body: resBody, headers: res.headers };
475
487
  if (cb)
476
- cb(result);
477
- return result;
488
+ cb(response);
489
+ return response;
478
490
  }
479
491
  catch (e) {
480
492
  const res = { status: e.response?.status || 500, statusCode: e.response?.status || 500, body: e.response?.data || e.message, headers: e.response?.headers || {} };
@@ -483,39 +495,32 @@ program.command('test')
483
495
  return res;
484
496
  }
485
497
  },
486
- _fetch: async (url) => {
487
- try {
488
- const res = await axios.get(url);
489
- return typeof res.data === 'string' ? res.data : JSON.stringify(res.data);
490
- }
491
- catch (e) {
492
- throw new Error(`HTTP Error ${e.response?.status || 500} fetching ${url}`);
493
- }
494
- },
495
- fetch: async (url) => {
496
- const res = await axios.get(url);
497
- return {
498
- status: res.status,
499
- statusCode: res.status,
500
- body: typeof res.data === 'string' ? res.data : JSON.stringify(res.data),
501
- headers: res.headers
502
- };
503
- },
504
498
  registerSettings: (schema) => {
505
499
  console.log(' [Mock SDK]: Plugin registered settings:', JSON.stringify(schema, null, 2));
506
500
  },
501
+ getPreference: (key) => {
502
+ return preferences[key] || null;
503
+ },
504
+ setPreference: (key, value) => {
505
+ preferences[key] = value;
506
+ return true;
507
+ },
507
508
  solveCaptcha: async (siteKey, url) => {
508
509
  console.log(' [Mock SDK]: solveCaptcha requested for ' + url + ' with key ' + siteKey);
509
510
  return "mock_captcha_token";
510
511
  },
511
- crypto: {
512
- decryptAES: (data, key, iv) => {
513
- return "decrypted(" + data + ")";
514
- }
515
- },
516
512
  btoa: (s) => Buffer.from(s).toString('base64'),
517
513
  atob: (s) => Buffer.from(s, 'base64').toString('utf8'),
518
514
  sendMessage: async (id, arg) => {
515
+ if (id === 'get_preference') {
516
+ const { key } = JSON.parse(arg);
517
+ return preferences[key] || null;
518
+ }
519
+ if (id === 'set_preference') {
520
+ const { key, value } = JSON.parse(arg);
521
+ preferences[key] = value;
522
+ return true;
523
+ }
519
524
  if (id === 'crypto_decrypt_aes') {
520
525
  const { data, key, iv } = JSON.parse(arg);
521
526
  try {
@@ -550,6 +555,7 @@ program.command('test')
550
555
  },
551
556
  globalThis: {},
552
557
  };
558
+ context.globalThis = context;
553
559
  const entityDefs = `
554
560
  class Actor {
555
561
  constructor(params) {
@@ -574,8 +580,10 @@ program.command('test')
574
580
  Object.assign(this, {
575
581
  type: 'movie',
576
582
  status: 'ongoing',
577
- vpnStatus: 'none',
583
+ playbackPolicy: 'none',
578
584
  isAdult: false,
585
+ streams: [],
586
+ syncData: {},
579
587
  ...params
580
588
  });
581
589
  }
@@ -587,6 +595,8 @@ program.command('test')
587
595
  season: 0,
588
596
  episode: 0,
589
597
  dubStatus: 'none',
598
+ playbackPolicy: 'none',
599
+ streams: [],
590
600
  ...params
591
601
  });
592
602
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skystream-cli",
3
- "version": "1.4.5",
3
+ "version": "1.4.7",
4
4
  "type": "module",
5
5
  "description": "SkyStream Plugin Development Kit & Repository Manager",
6
6
  "main": "dist/index.js",