skystream-cli 1.4.3 → 1.4.4

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 +86 -59
  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.3');
15
+ .version('1.4.4');
16
16
  // Schemas
17
17
  const pluginSchema = z.object({
18
18
  packageName: z.string().min(5).regex(/^[a-z0-9._-]+$/),
@@ -45,12 +45,18 @@ const JS_TEMPLATE = `(function() {
45
45
  */
46
46
  // var manifest is injected at runtime
47
47
 
48
+ // 1. (Optional) Register your plugin settings
49
+ registerSettings([
50
+ { id: "quality", name: "Default Quality", type: "select", options: ["1080p", "720p"], default: "1080p" },
51
+ { id: "prefer_dub", name: "Prefer Dubbed", type: "toggle", default: false }
52
+ ]);
48
53
 
49
54
  /**
50
55
  * Loads the home screen categories.
51
56
  * @param {(res: Response) => void} cb
52
57
  */
53
58
  async function getHome(cb) {
59
+ // Example: Using solveCaptcha if needed (await solveCaptcha(siteKey, url))
54
60
  try {
55
61
  // Dashboard Layout:
56
62
  // - "Trending" is a reserved category promoted to the Hero Carousel.
@@ -75,23 +81,22 @@ const JS_TEMPLATE = `(function() {
75
81
  title: "Example Series (Thumb)",
76
82
  url: \`\${manifest.baseUrl}/series\`,
77
83
  posterUrl: \`https://placehold.co/400x600.png?text=Series+Poster\`,
78
- type: "series", // Valid types: movie, series, anime, livestream
79
- description: "This category appears as a thumbnail row.", // (optional)
80
- headers: { "Referer": \`\${manifest.baseUrl}\` }, // (optional)
84
+ type: "series",
85
+ year: 2024,
86
+ score: 8.5,
87
+ status: "ongoing", // ongoing, completed, upcoming
88
+ description: "This category appears as a thumbnail row.",
89
+ cast: [
90
+ new Actor({ name: "John Doe", role: "Protagonist", image: "https://..." })
91
+ ],
81
92
  episodes: [
82
93
  new Episode({
83
94
  name: "Episode 1",
84
95
  url: \`\${manifest.baseUrl}/series/1\`,
85
96
  season: 1,
86
97
  episode: 1,
87
- posterUrl: \`https://placehold.co/400x600.png?text=EP1+Poster\`
88
- }),
89
- new Episode({
90
- name: "Episode 2",
91
- url: \`\${manifest.baseUrl}/series/2\`,
92
- season: 1,
93
- episode: 2,
94
- posterUrl: \`https://placehold.co/400x600.png?text=EP2+Poster\`
98
+ airDate: "2024-03-12",
99
+ dubStatus: "subbed" // subbed, dubbed, none
95
100
  })
96
101
  ]
97
102
  })
@@ -106,9 +111,10 @@ const JS_TEMPLATE = `(function() {
106
111
  /**
107
112
  * Searches for media items.
108
113
  * @param {string} query
114
+ * @param {number} page
109
115
  * @param {(res: Response) => void} cb
110
116
  */
111
- async function search(query, cb) {
117
+ async function search(query, page, cb) {
112
118
  try {
113
119
  // Standard: Return a List of items
114
120
  // Samples show both a movie and a series
@@ -409,7 +415,7 @@ program.command('validate')
409
415
  count++;
410
416
  }
411
417
  catch (e) {
412
- console.error(`✗ ${item} invalid: ${e.message}`);
418
+ console.error(`\u2717 ${item} invalid: ${e.message}`);
413
419
  if (e instanceof z.ZodError) {
414
420
  console.error(JSON.stringify(e.format(), null, 2));
415
421
  }
@@ -493,14 +499,24 @@ program.command('test')
493
499
  headers: res.headers
494
500
  };
495
501
  },
502
+ registerSettings: (schema) => {
503
+ console.log(' [Mock SDK]: Plugin registered settings:', JSON.stringify(schema, null, 2));
504
+ },
505
+ solveCaptcha: async (siteKey, url) => {
506
+ console.log(' [Mock SDK]: solveCaptcha requested for ' + url + ' with key ' + siteKey);
507
+ return "mock_captcha_token";
508
+ },
509
+ crypto: {
510
+ decryptAES: (data, key, iv) => {
511
+ return "decrypted(" + data + ")";
512
+ }
513
+ },
496
514
  btoa: (s) => Buffer.from(s).toString('base64'),
497
515
  atob: (s) => Buffer.from(s, 'base64').toString('utf8'),
498
516
  sendMessage: async (id, arg) => {
499
517
  if (id === 'crypto_decrypt_aes') {
500
518
  const { data, key, iv } = JSON.parse(arg);
501
519
  try {
502
- // Standardize key and iv to correct lengths
503
- // They are often passed as base64 strings
504
520
  const decodeBuffer = (s) => {
505
521
  return s.length % 4 === 0 && /^[A-Za-z0-9+/=]+$/.test(s) ? Buffer.from(s, 'base64') : Buffer.from(s, 'utf8');
506
522
  };
@@ -533,41 +549,50 @@ program.command('test')
533
549
  globalThis: {},
534
550
  };
535
551
  const entityDefs = `
552
+ class Actor {
553
+ constructor(params) {
554
+ Object.assign(this, params);
555
+ }
556
+ }
557
+
558
+ class Trailer {
559
+ constructor(params) {
560
+ Object.assign(this, params);
561
+ }
562
+ }
563
+
564
+ class NextAiring {
565
+ constructor(params) {
566
+ Object.assign(this, params);
567
+ }
568
+ }
569
+
536
570
  class MultimediaItem {
537
- constructor({ title, url, posterUrl, type, bannerUrl, description, episodes, headers, provider }) {
538
- this.title = title;
539
- this.url = url;
540
- this.posterUrl = posterUrl;
541
- this.type = type || 'movie';
542
- this.bannerUrl = bannerUrl;
543
- this.description = description;
544
- this.episodes = episodes;
545
- this.headers = headers;
546
- this.provider = provider;
571
+ constructor(params) {
572
+ Object.assign(this, {
573
+ type: 'movie',
574
+ status: 'ongoing',
575
+ vpnStatus: 'none',
576
+ isAdult: false,
577
+ ...params
578
+ });
547
579
  }
548
580
  }
549
581
 
550
582
  class Episode {
551
- constructor({ name, url, season, episode, description, posterUrl, headers }) {
552
- this.name = name;
553
- this.url = url;
554
- this.season = season || 0;
555
- this.episode = episode || 0;
556
- this.description = description;
557
- this.posterUrl = posterUrl;
558
- this.headers = headers;
583
+ constructor(params) {
584
+ Object.assign(this, {
585
+ season: 0,
586
+ episode: 0,
587
+ dubStatus: 'none',
588
+ ...params
589
+ });
559
590
  }
560
591
  }
561
592
 
562
593
  class StreamResult {
563
- constructor({ url, source, quality, headers, subtitles, drmKid, drmKey, licenseUrl }) {
564
- this.url = url;
565
- this.source = source || quality || 'Auto';
566
- this.headers = headers;
567
- this.subtitles = subtitles;
568
- this.drmKid = drmKid;
569
- this.drmKey = drmKey;
570
- this.licenseUrl = licenseUrl;
594
+ constructor(params) {
595
+ Object.assign(this, params);
571
596
  }
572
597
  }
573
598
 
@@ -617,21 +642,23 @@ program.command('test')
617
642
  const callback = (res) => {
618
643
  console.log('\n--- Result ---');
619
644
  if (res && res.success === false) {
620
- console.log(`\x1b[31mStatus: FAILED\x1b[0m`);
621
- console.log(`\x1b[31mError Code: ${res.errorCode || 'UNKNOWN'}\x1b[0m`);
645
+ console.log('\x1b[31mStatus: FAILED\x1b[0m');
646
+ console.log('\x1b[31mError Code: ' + (res.errorCode || 'UNKNOWN') + '\x1b[0m');
622
647
  if (res.message)
623
- console.log(`\x1b[31mMessage: ${res.message}\x1b[0m`);
648
+ console.log('\x1b[31mMessage: ' + res.message + '\x1b[0m');
624
649
  }
625
650
  else {
626
- console.log(`\x1b[32mStatus: SUCCESS\x1b[0m`);
651
+ console.log('\x1b[32mStatus: SUCCESS\x1b[0m');
627
652
  }
628
653
  console.log(JSON.stringify(res, null, 2));
629
654
  };
630
655
  try {
631
656
  if (options.function === 'getHome')
632
657
  await fn(callback);
658
+ else if (options.function === 'search')
659
+ await fn(options.query, 1, callback);
633
660
  else if (!options.query || options.query.trim() === "") {
634
- console.warn(`\x1b[33mWarning: Function '${options.function}' usually requires a query/URL (-q), but none was provided.\x1b[0m`);
661
+ console.warn('\x1b[33mWarning: Function \'' + options.function + '\' usually requires a query/URL (-q), but none was provided.\x1b[0m');
635
662
  await fn(options.query, callback);
636
663
  }
637
664
  else {
@@ -639,8 +666,8 @@ program.command('test')
639
666
  }
640
667
  }
641
668
  catch (e) {
642
- console.error(`\n\x1b[31m--- CRITICAL ERROR DURING EXECUTION ---\x1b[0m`);
643
- console.error(`\x1b[31m${e.stack || e.message}\x1b[0m\n`);
669
+ console.error('\n\x1b[31m--- CRITICAL ERROR DURING EXECUTION ---\x1b[0m');
670
+ console.error('\x1b[31m' + (e.stack || e.message) + '\x1b[0m\n');
644
671
  process.exit(2);
645
672
  }
646
673
  });
@@ -660,27 +687,27 @@ program.command('deploy')
660
687
  const catalog = [];
661
688
  // Standardize URL: Append /dist automatically
662
689
  const baseRaw = options.url.endsWith('/') ? options.url.slice(0, -1) : options.url;
663
- const distUrl = `${baseRaw}/dist`;
690
+ const distUrl = baseRaw + "/dist";
664
691
  for (const item of items) {
665
692
  const itemPath = path.join(rootDir, item);
666
693
  const mPath = path.join(itemPath, 'plugin.json');
667
694
  if (await fs.pathExists(mPath) && (await fs.stat(itemPath)).isDirectory()) {
668
695
  const manifest = await fs.readJson(mPath);
669
696
  const packageName = manifest.packageName || manifest.id || item;
670
- const bundleName = `${packageName}.sky`;
697
+ const bundleName = packageName + ".sky";
671
698
  const outPath = path.join(distDir, bundleName);
672
699
  const arch = archiver('zip', { zlib: { level: 9 } });
673
700
  arch.pipe(fs.createWriteStream(outPath));
674
701
  arch.file(mPath, { name: 'plugin.json' });
675
702
  arch.file(path.join(itemPath, 'plugin.js'), { name: 'plugin.js' });
676
703
  await arch.finalize();
677
- catalog.push({ ...manifest, url: `${distUrl}/${bundleName}` });
678
- console.log(`✓ Bundled ${manifest.packageName}`);
704
+ catalog.push({ ...manifest, url: distUrl + "/" + bundleName });
705
+ console.log("✓ Bundled " + manifest.packageName);
679
706
  }
680
707
  }
681
708
  const finalRepo = {
682
709
  ...repo,
683
- pluginLists: [`${distUrl}/plugins.json`]
710
+ pluginLists: [distUrl + "/plugins.json"]
684
711
  };
685
712
  await fs.writeJson(repoPath, finalRepo, { spaces: 2 });
686
713
  await fs.writeJson(path.join(distDir, 'plugins.json'), catalog, { spaces: 2 });
@@ -689,15 +716,15 @@ program.command('deploy')
689
716
  if (await fs.pathExists(readmePath)) {
690
717
  let readme = await fs.readFile(readmePath, 'utf8');
691
718
  const placeholder = 'https://raw.githubusercontent.com/USER_NAME/REPO_NAME/main/repo.json';
692
- const liveUrl = `${baseRaw}/repo.json`;
719
+ const liveUrl = baseRaw + "/repo.json";
693
720
  if (readme.includes(placeholder)) {
694
721
  readme = readme.replace(placeholder, liveUrl);
695
722
  await fs.writeFile(readmePath, readme);
696
- console.log(`✓ Updated README.md with live URL`);
723
+ console.log("✓ Updated README.md with live URL");
697
724
  }
698
725
  }
699
- console.log(`\nDeployment Complete. Assets generated in dist/`);
700
- console.log(`\nYour Repo Link for the app:`);
701
- console.log(`> ${baseRaw}/repo.json`);
726
+ console.log("\nDeployment Complete. Assets generated in dist/");
727
+ console.log("\nYour Repo Link for the app:");
728
+ console.log("> " + baseRaw + "/repo.json");
702
729
  });
703
730
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skystream-cli",
3
- "version": "1.4.3",
3
+ "version": "1.4.4",
4
4
  "type": "module",
5
5
  "description": "SkyStream Plugin Development Kit & Repository Manager",
6
6
  "main": "dist/index.js",