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.
- package/dist/index.js +79 -30
- 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.
|
|
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
|
-
//
|
|
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:
|
|
63
|
+
posterUrl: \`https://placehold.co/400x600.png?text=Trending+Movie\`,
|
|
61
64
|
type: "movie", // Valid types: movie, series, anime, livestream
|
|
62
|
-
bannerUrl:
|
|
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:
|
|
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:
|
|
89
|
-
type: "movie",
|
|
90
|
-
bannerUrl:
|
|
91
|
-
description: "Plot summary here...",
|
|
92
|
-
headers: { "Referer": \`\${manifest.baseUrl}\` }
|
|
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:
|
|
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
|
|
151
|
+
title: "Example Series Full Details",
|
|
113
152
|
url: url,
|
|
114
|
-
posterUrl:
|
|
115
|
-
type: "
|
|
116
|
-
bannerUrl:
|
|
117
|
-
description: "This is a detailed description of the
|
|
118
|
-
headers: { "Referer": \`\${manifest.baseUrl}\` },
|
|
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,
|
|
124
|
-
episode: 1,
|
|
125
|
-
description: "Episode summary...",
|
|
126
|
-
posterUrl:
|
|
127
|
-
headers: { "Referer": \`\${manifest.baseUrl}\` }
|
|
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:
|
|
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
|