skystream-cli 1.3.0 → 1.3.6

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 +79 -30
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ const program = new Command();
9
9
  program
10
10
  .name('skystream')
11
11
  .description('SkyStream Plugin Development Kit CLI (Sky Gen 2)')
12
- .version('1.3.0');
12
+ .version('1.3.6');
13
13
  // Schemas
14
14
  const pluginSchema = z.object({
15
15
  packageName: z.string().min(5).regex(/^[a-z0-9._-]+$/),
@@ -49,25 +49,54 @@ const JS_TEMPLATE = `(function() {
49
49
  */
50
50
  async function getHome(cb) {
51
51
  try {
52
- // Standard: Return a Map of Category -> List of items
52
+ // Dashboard Layout:
53
+ // - "Trending" is a reserved category promoted to the Hero Carousel.
54
+ // - Other categories appear as horizontal thumbnail rows.
55
+ // - If "Trending" is missing, the first category is used for the carousel.
53
56
  cb({
54
57
  success: true,
55
58
  data: {
56
59
  "Trending": [
57
60
  new MultimediaItem({
58
- title: "Example Movie",
61
+ title: "Example Movie (Carousel)",
59
62
  url: \`\${manifest.baseUrl}/movie\`,
60
- posterUrl: \`\${manifest.baseUrl}/poster.jpg\`,
63
+ posterUrl: \`https://placehold.co/400x600.png?text=Trending+Movie\`,
61
64
  type: "movie", // Valid types: movie, series, anime, livestream
62
- bannerUrl: \`\${manifest.baseUrl}/banner.jpg\`, // (optional)
65
+ bannerUrl: \`https://placehold.co/1280x720.png?text=Trending+Banner\`, // (optional)
63
66
  description: "Plot summary here...", // (optional)
64
67
  headers: { "Referer": \`\${manifest.baseUrl}\` } // (optional)
65
68
  })
66
- ]
69
+ ],
70
+ "Latest Series": [
71
+ new MultimediaItem({
72
+ title: "Example Series (Thumb)",
73
+ url: \`\${manifest.baseUrl}/series\`,
74
+ posterUrl: \`https://placehold.co/400x600.png?text=Series+Poster\`,
75
+ type: "series", // Valid types: movie, series, anime, livestream
76
+ description: "This category appears as a thumbnail row.", // (optional)
77
+ headers: { "Referer": \`\${manifest.baseUrl}\` }, // (optional)
78
+ episodes: [
79
+ new Episode({
80
+ name: "Episode 1",
81
+ url: \`\${manifest.baseUrl}/series/1\`,
82
+ season: 1,
83
+ episode: 1,
84
+ posterUrl: \`https://placehold.co/400x600.png?text=EP1+Poster\`
85
+ }),
86
+ new Episode({
87
+ name: "Episode 2",
88
+ url: \`\${manifest.baseUrl}/series/2\`,
89
+ season: 1,
90
+ episode: 2,
91
+ posterUrl: \`https://placehold.co/400x600.png?text=EP2+Poster\`
92
+ })
93
+ ]
94
+ })
95
+ ]
67
96
  }
68
97
  });
69
98
  } catch (e) {
70
- cb({ success: false, errorCode: "PARSE_ERROR", message: (e instanceof Error) ? e.message : String(e) });
99
+ cb({ success: false, errorCode: "PARSE_ERROR", message: e.stack });
71
100
  }
72
101
  }
73
102
 
@@ -79,22 +108,31 @@ const JS_TEMPLATE = `(function() {
79
108
  async function search(query, cb) {
80
109
  try {
81
110
  // Standard: Return a List of items
111
+ // Samples show both a movie and a series
82
112
  cb({
83
113
  success: true,
84
114
  data: [
85
115
  new MultimediaItem({
86
- title: "Example Movie",
116
+ title: "Example Movie (Search Result)",
87
117
  url: \`\${manifest.baseUrl}/movie\`,
88
- posterUrl: \`\${manifest.baseUrl}/poster.jpg\`,
89
- type: "movie", // Valid types: movie, series, anime, livestream
90
- bannerUrl: \`\${manifest.baseUrl}/banner.jpg\`, // (optional)
91
- description: "Plot summary here...", // (optional)
92
- headers: { "Referer": \`\${manifest.baseUrl}\` } // (optional)
118
+ posterUrl: \`https://placehold.co/400x600.png?text=Search+Movie\`,
119
+ type: "movie",
120
+ bannerUrl: \`https://placehold.co/1280x720.png?text=Search+Banner\`,
121
+ description: "Plot summary here...",
122
+ headers: { "Referer": \`\${manifest.baseUrl}\` }
123
+ }),
124
+ new MultimediaItem({
125
+ title: "Example Series (Search Result)",
126
+ url: \`\${manifest.baseUrl}/series\`,
127
+ posterUrl: \`https://placehold.co/400x600.png?text=Search+Series\`,
128
+ type: "series",
129
+ description: "A series found in search.",
130
+ headers: { "Referer": \`\${manifest.baseUrl}\` }
93
131
  })
94
132
  ]
95
133
  });
96
134
  } catch (e) {
97
- cb({ success: false, errorCode: "SEARCH_ERROR", message: (e instanceof Error) ? e.message : String(e) });
135
+ cb({ success: false, errorCode: "SEARCH_ERROR", message: e.stack });
98
136
  }
99
137
  }
100
138
 
@@ -106,31 +144,41 @@ const JS_TEMPLATE = `(function() {
106
144
  async function load(url, cb) {
107
145
  try {
108
146
  // Standard: Return a single item with full metadata
147
+ // Sample shows a series with episodes
109
148
  cb({
110
149
  success: true,
111
150
  data: new MultimediaItem({
112
- title: "Example Movie Full Details",
151
+ title: "Example Series Full Details",
113
152
  url: url,
114
- posterUrl: \`\${manifest.baseUrl}/poster.jpg\`,
115
- type: "movie", // Valid types: movie, series, anime, livestream
116
- bannerUrl: \`\${manifest.baseUrl}/banner.jpg\`, // (optional)
117
- description: "This is a detailed description of the movie.", // (optional)
118
- headers: { "Referer": \`\${manifest.baseUrl}\` }, // (optional)
153
+ posterUrl: \`https://placehold.co/400x600.png?text=Series+Details\`,
154
+ type: "series",
155
+ bannerUrl: \`https://placehold.co/1280x720.png?text=Series+Banner\`,
156
+ description: "This is a detailed description of the media.",
157
+ headers: { "Referer": \`\${manifest.baseUrl}\` },
119
158
  episodes: [
120
159
  new Episode({
121
160
  name: "Episode 1",
122
161
  url: \`\${manifest.baseUrl}/watch/1\`,
123
- season: 1, // (optional)
124
- episode: 1, // (optional)
125
- description: "Episode summary...", // (optional)
126
- posterUrl: \`\${manifest.baseUrl}/ep-poster.jpg\`, // (optional)
127
- headers: { "Referer": \`\${manifest.baseUrl}\` } // (optional)
162
+ season: 1,
163
+ episode: 1,
164
+ description: "Episode summary...",
165
+ posterUrl: \`https://placehold.co/400x600.png?text=Episode+Poster\`,
166
+ headers: { "Referer": \`\${manifest.baseUrl}\` }
167
+ }),
168
+ new Episode({
169
+ name: "Episode 2",
170
+ url: \`\${manifest.baseUrl}/watch/2\`,
171
+ season: 1,
172
+ episode: 2,
173
+ description: "Next episode summary...",
174
+ posterUrl: \`https://placehold.co/400x600.png?text=Episode+Poster\`,
175
+ headers: { "Referer": \`\${manifest.baseUrl}\` }
128
176
  })
129
177
  ]
130
178
  })
131
179
  });
132
180
  } catch (e) {
133
- cb({ success: false, errorCode: "LOAD_ERROR", message: (e instanceof Error) ? e.message : String(e) });
181
+ cb({ success: false, errorCode: "LOAD_ERROR", message: e.stack });
134
182
  }
135
183
  }
136
184
 
@@ -388,13 +436,13 @@ program.command('test')
388
436
  http_get: async (url, headers, cb) => {
389
437
  try {
390
438
  const res = await axios.get(url, { headers: headers || {} });
391
- const result = { statusCode: res.status, body: typeof res.data === 'string' ? res.data : JSON.stringify(res.data), headers: res.headers };
439
+ const result = { status: res.status, statusCode: res.status, body: typeof res.data === 'string' ? res.data : JSON.stringify(res.data), headers: res.headers };
392
440
  if (cb)
393
441
  cb(result);
394
442
  return result;
395
443
  }
396
444
  catch (e) {
397
- const res = { statusCode: e.response?.status || 500, body: e.response?.data || e.message, headers: e.response?.headers || {} };
445
+ const res = { status: e.response?.status || 500, statusCode: e.response?.status || 500, body: e.response?.data || e.message, headers: e.response?.headers || {} };
398
446
  if (cb)
399
447
  cb(res);
400
448
  return res;
@@ -403,13 +451,13 @@ program.command('test')
403
451
  http_post: async (url, headers, body, cb) => {
404
452
  try {
405
453
  const res = await axios.post(url, body, { headers: headers || {} });
406
- const result = { statusCode: res.status, body: typeof res.data === 'string' ? res.data : JSON.stringify(res.data), headers: res.headers };
454
+ const result = { status: res.status, statusCode: res.status, body: typeof res.data === 'string' ? res.data : JSON.stringify(res.data), headers: res.headers };
407
455
  if (cb)
408
456
  cb(result);
409
457
  return result;
410
458
  }
411
459
  catch (e) {
412
- const res = { statusCode: e.response?.status || 500, body: e.response?.data || e.message, headers: e.response?.headers || {} };
460
+ const res = { status: e.response?.status || 500, statusCode: e.response?.status || 500, body: e.response?.data || e.message, headers: e.response?.headers || {} };
413
461
  if (cb)
414
462
  cb(res);
415
463
  return res;
@@ -427,6 +475,7 @@ program.command('test')
427
475
  fetch: async (url) => {
428
476
  const res = await axios.get(url);
429
477
  return {
478
+ status: res.status,
430
479
  statusCode: res.status,
431
480
  body: typeof res.data === 'string' ? res.data : JSON.stringify(res.data),
432
481
  headers: res.headers
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skystream-cli",
3
- "version": "1.3.0",
3
+ "version": "1.3.6",
4
4
  "type": "module",
5
5
  "description": "SkyStream Plugin Development Kit & Repository Manager",
6
6
  "main": "dist/index.js",