skystream-cli 1.4.3 → 1.4.5

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 +96 -67
  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,25 +81,8 @@ 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)
81
- episodes: [
82
- new Episode({
83
- name: "Episode 1",
84
- url: \`\${manifest.baseUrl}/series/1\`,
85
- season: 1,
86
- 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\`
95
- })
96
- ]
84
+ type: "series",
85
+ description: "This category appears as a thumbnail row."
97
86
  })
98
87
  ]
99
88
  }
@@ -106,9 +95,10 @@ const JS_TEMPLATE = `(function() {
106
95
  /**
107
96
  * Searches for media items.
108
97
  * @param {string} query
98
+ * @param {number} page
109
99
  * @param {(res: Response) => void} cb
110
100
  */
111
- async function search(query, cb) {
101
+ async function search(query, page, cb) {
112
102
  try {
113
103
  // Standard: Return a List of items
114
104
  // Samples show both a movie and a series
@@ -157,6 +147,24 @@ const JS_TEMPLATE = `(function() {
157
147
  type: "series",
158
148
  bannerUrl: \`https://placehold.co/1280x720.png?text=Series+Banner\`,
159
149
  description: "This is a detailed description of the media.",
150
+ year: 2024,
151
+ score: 8.5,
152
+ duration: 120, // (optional, in minutes)
153
+ status: "ongoing", // ongoing, completed, upcoming
154
+ contentRating: "PG-13",
155
+ logoUrl: \`https://placehold.co/200x100.png?text=Logo\`,
156
+ isAdult: false,
157
+ tags: ["Action", "Adventure"],
158
+ cast: [
159
+ new Actor({ name: "John Doe", role: "Protagonist", image: "https://placehold.co/200x300.png" })
160
+ ],
161
+ trailers: [
162
+ new Trailer({ name: "Official Trailer", url: "https://www.youtube.com/watch?v=..." })
163
+ ],
164
+ nextAiring: new NextAiring({ episode: 5, season: 1, airDate: "2024-04-01" }),
165
+ recommendations: [
166
+ new MultimediaItem({ title: "Similar Show", url: \`\${manifest.baseUrl}/similar\`, posterUrl: "...", type: "series" })
167
+ ],
160
168
  headers: { "Referer": \`\${manifest.baseUrl}\` },
161
169
  episodes: [
162
170
  new Episode({
@@ -409,7 +417,7 @@ program.command('validate')
409
417
  count++;
410
418
  }
411
419
  catch (e) {
412
- console.error(`✗ ${item} invalid: ${e.message}`);
420
+ console.error(`\u2717 ${item} invalid: ${e.message}`);
413
421
  if (e instanceof z.ZodError) {
414
422
  console.error(JSON.stringify(e.format(), null, 2));
415
423
  }
@@ -493,14 +501,24 @@ program.command('test')
493
501
  headers: res.headers
494
502
  };
495
503
  },
504
+ registerSettings: (schema) => {
505
+ console.log(' [Mock SDK]: Plugin registered settings:', JSON.stringify(schema, null, 2));
506
+ },
507
+ solveCaptcha: async (siteKey, url) => {
508
+ console.log(' [Mock SDK]: solveCaptcha requested for ' + url + ' with key ' + siteKey);
509
+ return "mock_captcha_token";
510
+ },
511
+ crypto: {
512
+ decryptAES: (data, key, iv) => {
513
+ return "decrypted(" + data + ")";
514
+ }
515
+ },
496
516
  btoa: (s) => Buffer.from(s).toString('base64'),
497
517
  atob: (s) => Buffer.from(s, 'base64').toString('utf8'),
498
518
  sendMessage: async (id, arg) => {
499
519
  if (id === 'crypto_decrypt_aes') {
500
520
  const { data, key, iv } = JSON.parse(arg);
501
521
  try {
502
- // Standardize key and iv to correct lengths
503
- // They are often passed as base64 strings
504
522
  const decodeBuffer = (s) => {
505
523
  return s.length % 4 === 0 && /^[A-Za-z0-9+/=]+$/.test(s) ? Buffer.from(s, 'base64') : Buffer.from(s, 'utf8');
506
524
  };
@@ -533,41 +551,50 @@ program.command('test')
533
551
  globalThis: {},
534
552
  };
535
553
  const entityDefs = `
554
+ class Actor {
555
+ constructor(params) {
556
+ Object.assign(this, params);
557
+ }
558
+ }
559
+
560
+ class Trailer {
561
+ constructor(params) {
562
+ Object.assign(this, params);
563
+ }
564
+ }
565
+
566
+ class NextAiring {
567
+ constructor(params) {
568
+ Object.assign(this, params);
569
+ }
570
+ }
571
+
536
572
  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;
573
+ constructor(params) {
574
+ Object.assign(this, {
575
+ type: 'movie',
576
+ status: 'ongoing',
577
+ vpnStatus: 'none',
578
+ isAdult: false,
579
+ ...params
580
+ });
547
581
  }
548
582
  }
549
583
 
550
584
  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;
585
+ constructor(params) {
586
+ Object.assign(this, {
587
+ season: 0,
588
+ episode: 0,
589
+ dubStatus: 'none',
590
+ ...params
591
+ });
559
592
  }
560
593
  }
561
594
 
562
595
  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;
596
+ constructor(params) {
597
+ Object.assign(this, params);
571
598
  }
572
599
  }
573
600
 
@@ -617,21 +644,23 @@ program.command('test')
617
644
  const callback = (res) => {
618
645
  console.log('\n--- Result ---');
619
646
  if (res && res.success === false) {
620
- console.log(`\x1b[31mStatus: FAILED\x1b[0m`);
621
- console.log(`\x1b[31mError Code: ${res.errorCode || 'UNKNOWN'}\x1b[0m`);
647
+ console.log('\x1b[31mStatus: FAILED\x1b[0m');
648
+ console.log('\x1b[31mError Code: ' + (res.errorCode || 'UNKNOWN') + '\x1b[0m');
622
649
  if (res.message)
623
- console.log(`\x1b[31mMessage: ${res.message}\x1b[0m`);
650
+ console.log('\x1b[31mMessage: ' + res.message + '\x1b[0m');
624
651
  }
625
652
  else {
626
- console.log(`\x1b[32mStatus: SUCCESS\x1b[0m`);
653
+ console.log('\x1b[32mStatus: SUCCESS\x1b[0m');
627
654
  }
628
655
  console.log(JSON.stringify(res, null, 2));
629
656
  };
630
657
  try {
631
658
  if (options.function === 'getHome')
632
659
  await fn(callback);
660
+ else if (options.function === 'search')
661
+ await fn(options.query, 1, callback);
633
662
  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`);
663
+ console.warn('\x1b[33mWarning: Function \'' + options.function + '\' usually requires a query/URL (-q), but none was provided.\x1b[0m');
635
664
  await fn(options.query, callback);
636
665
  }
637
666
  else {
@@ -639,8 +668,8 @@ program.command('test')
639
668
  }
640
669
  }
641
670
  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`);
671
+ console.error('\n\x1b[31m--- CRITICAL ERROR DURING EXECUTION ---\x1b[0m');
672
+ console.error('\x1b[31m' + (e.stack || e.message) + '\x1b[0m\n');
644
673
  process.exit(2);
645
674
  }
646
675
  });
@@ -660,27 +689,27 @@ program.command('deploy')
660
689
  const catalog = [];
661
690
  // Standardize URL: Append /dist automatically
662
691
  const baseRaw = options.url.endsWith('/') ? options.url.slice(0, -1) : options.url;
663
- const distUrl = `${baseRaw}/dist`;
692
+ const distUrl = baseRaw + "/dist";
664
693
  for (const item of items) {
665
694
  const itemPath = path.join(rootDir, item);
666
695
  const mPath = path.join(itemPath, 'plugin.json');
667
696
  if (await fs.pathExists(mPath) && (await fs.stat(itemPath)).isDirectory()) {
668
697
  const manifest = await fs.readJson(mPath);
669
698
  const packageName = manifest.packageName || manifest.id || item;
670
- const bundleName = `${packageName}.sky`;
699
+ const bundleName = packageName + ".sky";
671
700
  const outPath = path.join(distDir, bundleName);
672
701
  const arch = archiver('zip', { zlib: { level: 9 } });
673
702
  arch.pipe(fs.createWriteStream(outPath));
674
703
  arch.file(mPath, { name: 'plugin.json' });
675
704
  arch.file(path.join(itemPath, 'plugin.js'), { name: 'plugin.js' });
676
705
  await arch.finalize();
677
- catalog.push({ ...manifest, url: `${distUrl}/${bundleName}` });
678
- console.log(`✓ Bundled ${manifest.packageName}`);
706
+ catalog.push({ ...manifest, url: distUrl + "/" + bundleName });
707
+ console.log("✓ Bundled " + manifest.packageName);
679
708
  }
680
709
  }
681
710
  const finalRepo = {
682
711
  ...repo,
683
- pluginLists: [`${distUrl}/plugins.json`]
712
+ pluginLists: [distUrl + "/plugins.json"]
684
713
  };
685
714
  await fs.writeJson(repoPath, finalRepo, { spaces: 2 });
686
715
  await fs.writeJson(path.join(distDir, 'plugins.json'), catalog, { spaces: 2 });
@@ -689,15 +718,15 @@ program.command('deploy')
689
718
  if (await fs.pathExists(readmePath)) {
690
719
  let readme = await fs.readFile(readmePath, 'utf8');
691
720
  const placeholder = 'https://raw.githubusercontent.com/USER_NAME/REPO_NAME/main/repo.json';
692
- const liveUrl = `${baseRaw}/repo.json`;
721
+ const liveUrl = baseRaw + "/repo.json";
693
722
  if (readme.includes(placeholder)) {
694
723
  readme = readme.replace(placeholder, liveUrl);
695
724
  await fs.writeFile(readmePath, readme);
696
- console.log(`✓ Updated README.md with live URL`);
725
+ console.log("✓ Updated README.md with live URL");
697
726
  }
698
727
  }
699
- console.log(`\nDeployment Complete. Assets generated in dist/`);
700
- console.log(`\nYour Repo Link for the app:`);
701
- console.log(`> ${baseRaw}/repo.json`);
728
+ console.log("\nDeployment Complete. Assets generated in dist/");
729
+ console.log("\nYour Repo Link for the app:");
730
+ console.log("> " + baseRaw + "/repo.json");
702
731
  });
703
732
  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.5",
4
4
  "type": "module",
5
5
  "description": "SkyStream Plugin Development Kit & Repository Manager",
6
6
  "main": "dist/index.js",