skystream-cli 1.0.0 → 1.2.2
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 +91 -25
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9,12 +9,11 @@ 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.2.
|
|
12
|
+
.version('1.2.2');
|
|
13
13
|
// Schemas
|
|
14
14
|
const pluginSchema = z.object({
|
|
15
|
-
|
|
15
|
+
packageName: z.string().min(5).regex(/^[a-z0-9._-]+$/),
|
|
16
16
|
name: z.string().min(1),
|
|
17
|
-
internalName: z.string().min(1).regex(/^[A-Z0-9]+$/),
|
|
18
17
|
version: z.number().int().positive(),
|
|
19
18
|
description: z.string().min(1),
|
|
20
19
|
authors: z.array(z.string()).min(1),
|
|
@@ -23,7 +22,7 @@ const pluginSchema = z.object({
|
|
|
23
22
|
});
|
|
24
23
|
const repoSchema = z.object({
|
|
25
24
|
name: z.string().min(1),
|
|
26
|
-
|
|
25
|
+
packageName: z.string().min(3).regex(/^[a-z0-9._-]+$/),
|
|
27
26
|
description: z.string().min(1),
|
|
28
27
|
manifestVersion: z.number().int().positive(),
|
|
29
28
|
pluginLists: z.array(z.string().url()),
|
|
@@ -48,8 +47,23 @@ const JS_TEMPLATE = `(function() {
|
|
|
48
47
|
*/
|
|
49
48
|
async function getHome(cb) {
|
|
50
49
|
try {
|
|
51
|
-
//
|
|
52
|
-
cb({
|
|
50
|
+
// Standard: Return a Map of Category -> List of items
|
|
51
|
+
cb({
|
|
52
|
+
success: true,
|
|
53
|
+
data: {
|
|
54
|
+
"Trending": [
|
|
55
|
+
new MultimediaItem({
|
|
56
|
+
title: "Example Movie",
|
|
57
|
+
url: "https://site.com/movie",
|
|
58
|
+
posterUrl: "https://site.com/poster.jpg",
|
|
59
|
+
type: "movie", // Valid types: movie, series, anime, livestream
|
|
60
|
+
bannerUrl: "https://site.com/banner.jpg", // (optional)
|
|
61
|
+
description: "Plot summary here...", // (optional)
|
|
62
|
+
headers: { "Referer": "https://site.com" } // (optional)
|
|
63
|
+
})
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
});
|
|
53
67
|
} catch (e) {
|
|
54
68
|
cb({ success: false, errorCode: "PARSE_ERROR", message: (e instanceof Error) ? e.message : String(e) });
|
|
55
69
|
}
|
|
@@ -62,7 +76,21 @@ const JS_TEMPLATE = `(function() {
|
|
|
62
76
|
*/
|
|
63
77
|
async function search(query, cb) {
|
|
64
78
|
try {
|
|
65
|
-
|
|
79
|
+
// Standard: Return a List of items
|
|
80
|
+
cb({
|
|
81
|
+
success: true,
|
|
82
|
+
data: [
|
|
83
|
+
new MultimediaItem({
|
|
84
|
+
title: "Example Movie",
|
|
85
|
+
url: "https://site.com/movie",
|
|
86
|
+
posterUrl: "https://site.com/poster.jpg",
|
|
87
|
+
type: "movie", // Valid types: movie, series, anime, livestream
|
|
88
|
+
bannerUrl: "https://site.com/banner.jpg", // (optional)
|
|
89
|
+
description: "Plot summary here...", // (optional)
|
|
90
|
+
headers: { "Referer": "https://site.com" } // (optional)
|
|
91
|
+
})
|
|
92
|
+
]
|
|
93
|
+
});
|
|
66
94
|
} catch (e) {
|
|
67
95
|
cb({ success: false, errorCode: "SEARCH_ERROR", message: (e instanceof Error) ? e.message : String(e) });
|
|
68
96
|
}
|
|
@@ -75,7 +103,30 @@ const JS_TEMPLATE = `(function() {
|
|
|
75
103
|
*/
|
|
76
104
|
function load(url, cb) {
|
|
77
105
|
try {
|
|
78
|
-
|
|
106
|
+
// Standard: Return a single item with full metadata
|
|
107
|
+
cb({
|
|
108
|
+
success: true,
|
|
109
|
+
data: new MultimediaItem({
|
|
110
|
+
title: "Example Movie Full Details",
|
|
111
|
+
url: url,
|
|
112
|
+
posterUrl: "https://site.com/poster.jpg",
|
|
113
|
+
type: "movie", // Valid types: movie, series, anime, livestream
|
|
114
|
+
bannerUrl: "https://site.com/banner.jpg", // (optional)
|
|
115
|
+
description: "This is a detailed description of the movie.", // (optional)
|
|
116
|
+
headers: { "Referer": "https://site.com" }, // (optional)
|
|
117
|
+
episodes: [
|
|
118
|
+
new Episode({
|
|
119
|
+
name: "Episode 1",
|
|
120
|
+
url: "https://site.com/watch/1",
|
|
121
|
+
season: 1, // (optional)
|
|
122
|
+
episode: 1, // (optional)
|
|
123
|
+
description: "Episode summary...", // (optional)
|
|
124
|
+
posterUrl: "https://site.com/ep-poster.jpg", // (optional)
|
|
125
|
+
headers: { "Referer": "https://site.com" } // (optional)
|
|
126
|
+
})
|
|
127
|
+
]
|
|
128
|
+
})
|
|
129
|
+
});
|
|
79
130
|
} catch (e) {
|
|
80
131
|
cb({ success: false, errorCode: "LOAD_ERROR", message: (e instanceof Error) ? e.message : String(e) });
|
|
81
132
|
}
|
|
@@ -88,7 +139,23 @@ const JS_TEMPLATE = `(function() {
|
|
|
88
139
|
*/
|
|
89
140
|
async function loadStreams(url, cb) {
|
|
90
141
|
try {
|
|
91
|
-
|
|
142
|
+
// Standard: Return a List of stream urls
|
|
143
|
+
cb({
|
|
144
|
+
success: true,
|
|
145
|
+
data: [
|
|
146
|
+
new StreamResult({
|
|
147
|
+
url: "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8",
|
|
148
|
+
quality: "1080p", // (optional)
|
|
149
|
+
headers: { "Referer": "https://site.com" }, // (optional)
|
|
150
|
+
subtitles: [
|
|
151
|
+
{ url: "https://site.com/sub.vtt", label: "English", lang: "en" } // (optional)
|
|
152
|
+
],
|
|
153
|
+
drmKid: "kid_value", // (optional)
|
|
154
|
+
drmKey: "key_value", // (optional)
|
|
155
|
+
licenseUrl: "https://license-server.com" // (optional)
|
|
156
|
+
})
|
|
157
|
+
]
|
|
158
|
+
});
|
|
92
159
|
} catch (e) {
|
|
93
160
|
cb({ success: false, errorCode: "STREAM_ERROR", message: (e instanceof Error) ? e.message : String(e) });
|
|
94
161
|
}
|
|
@@ -163,7 +230,7 @@ jobs:
|
|
|
163
230
|
- name: Build Repository
|
|
164
231
|
run: |
|
|
165
232
|
npm install -g skystream-cli
|
|
166
|
-
skystream build -u https://raw.githubusercontent.com/\${{ github.repository }}
|
|
233
|
+
skystream build -u https://raw.githubusercontent.com/\${{ github.repository }}/main
|
|
167
234
|
|
|
168
235
|
- name: Commit and Push changes
|
|
169
236
|
run: |
|
|
@@ -194,11 +261,11 @@ program.command('init')
|
|
|
194
261
|
const projectSlug = projectName.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
|
|
195
262
|
const repo = {
|
|
196
263
|
name: projectName,
|
|
197
|
-
|
|
264
|
+
packageName: options.packageName,
|
|
198
265
|
description: options.description,
|
|
199
266
|
manifestVersion: 1,
|
|
200
267
|
pluginLists: [
|
|
201
|
-
`
|
|
268
|
+
`https://raw.githubusercontent.com/USER_NAME/REPO_NAME/main/dist/plugins.json`
|
|
202
269
|
]
|
|
203
270
|
};
|
|
204
271
|
await fs.writeJson(path.join(rootDir, 'repo.json'), repo, { spaces: 2 });
|
|
@@ -214,9 +281,8 @@ program.command('init')
|
|
|
214
281
|
const pluginDir = path.join(rootDir, pluginSlug);
|
|
215
282
|
await fs.ensureDir(pluginDir);
|
|
216
283
|
const pluginManifest = {
|
|
217
|
-
|
|
284
|
+
packageName: `${packageName}.${pluginSlug}`,
|
|
218
285
|
name: pluginName,
|
|
219
|
-
internalName: pluginName.toUpperCase().replace(/\s+/g, ''),
|
|
220
286
|
version: 1,
|
|
221
287
|
description: `${pluginName} plugin (Sky Gen 2)`,
|
|
222
288
|
authors: [options.author],
|
|
@@ -227,7 +293,7 @@ program.command('init')
|
|
|
227
293
|
await fs.writeFile(path.join(pluginDir, 'plugin.js'), JS_TEMPLATE);
|
|
228
294
|
console.log('\nSky Gen 2 Repository successfully initialized!');
|
|
229
295
|
console.log(`Project Directory: ${rootDir}`);
|
|
230
|
-
console.log(`First Plugin
|
|
296
|
+
console.log(`First Plugin Package Name: ${pluginManifest.packageName}`);
|
|
231
297
|
});
|
|
232
298
|
program.command('add')
|
|
233
299
|
.description('Add a new Sky Gen 2 plugin to the repository')
|
|
@@ -249,11 +315,10 @@ program.command('add')
|
|
|
249
315
|
process.exit(1);
|
|
250
316
|
}
|
|
251
317
|
// Guess package-name from repo id
|
|
252
|
-
const packageName = repo.
|
|
318
|
+
const packageName = repo.packageName;
|
|
253
319
|
const pluginManifest = {
|
|
254
|
-
|
|
320
|
+
packageName: `${packageName}.${pluginSlug}`,
|
|
255
321
|
name: pluginName,
|
|
256
|
-
internalName: pluginName.toUpperCase().replace(/\s+/g, ''),
|
|
257
322
|
version: 1,
|
|
258
323
|
description: options.description || `${pluginName} plugin for ${repo.name}`,
|
|
259
324
|
authors: [options.author || repo.author || "Developer"],
|
|
@@ -263,7 +328,7 @@ program.command('add')
|
|
|
263
328
|
await fs.ensureDir(pluginDir);
|
|
264
329
|
await fs.writeJson(path.join(pluginDir, 'plugin.json'), pluginManifest, { spaces: 2 });
|
|
265
330
|
await fs.writeFile(path.join(pluginDir, 'plugin.js'), JS_TEMPLATE);
|
|
266
|
-
console.log(`✓ Added Plugin: ${pluginName} (
|
|
331
|
+
console.log(`✓ Added Plugin: ${pluginName} (Package: ${pluginManifest.packageName})`);
|
|
267
332
|
});
|
|
268
333
|
program.command('validate')
|
|
269
334
|
.description('Validate all plugins in the repo')
|
|
@@ -278,13 +343,13 @@ program.command('validate')
|
|
|
278
343
|
try {
|
|
279
344
|
const manifest = await fs.readJson(manifestPath);
|
|
280
345
|
pluginSchema.parse(manifest);
|
|
281
|
-
console.log(`✓ ${manifest.
|
|
346
|
+
console.log(`✓ ${manifest.packageName}: Manifest OK`);
|
|
282
347
|
const js = await fs.readFile(path.join(itemPath, 'plugin.js'), 'utf8');
|
|
283
348
|
if (js.includes('globalThis.getHome = getHome')) {
|
|
284
|
-
console.log(`✓ ${manifest.
|
|
349
|
+
console.log(`✓ ${manifest.packageName}: Logic OK`);
|
|
285
350
|
}
|
|
286
351
|
else {
|
|
287
|
-
console.warn(`! ${manifest.
|
|
352
|
+
console.warn(`! ${manifest.packageName}: Missing exports`);
|
|
288
353
|
}
|
|
289
354
|
count++;
|
|
290
355
|
}
|
|
@@ -309,7 +374,7 @@ program.command('test')
|
|
|
309
374
|
const jsPath = path.join(pluginDir, 'plugin.js');
|
|
310
375
|
const manifest = await fs.readJson(manifestPath);
|
|
311
376
|
const jsContent = await fs.readFile(jsPath, 'utf8');
|
|
312
|
-
console.log(`\n--- Testing ${manifest.
|
|
377
|
+
console.log(`\n--- Testing ${manifest.packageName} -> ${options.function} ---`);
|
|
313
378
|
const context = {
|
|
314
379
|
manifest,
|
|
315
380
|
console: { log: (...args) => console.log(' [JS]:', ...args), error: (...args) => console.error(' [JS ERR]:', ...args) },
|
|
@@ -370,7 +435,8 @@ program.command('build')
|
|
|
370
435
|
const mPath = path.join(itemPath, 'plugin.json');
|
|
371
436
|
if (await fs.pathExists(mPath) && (await fs.stat(itemPath)).isDirectory()) {
|
|
372
437
|
const manifest = await fs.readJson(mPath);
|
|
373
|
-
const
|
|
438
|
+
const packageName = manifest.packageName || manifest.id || item;
|
|
439
|
+
const bundleName = `${packageName}.sky`;
|
|
374
440
|
const outPath = path.join(distDir, bundleName);
|
|
375
441
|
const arch = archiver('zip', { zlib: { level: 9 } });
|
|
376
442
|
arch.pipe(fs.createWriteStream(outPath));
|
|
@@ -378,7 +444,7 @@ program.command('build')
|
|
|
378
444
|
arch.file(path.join(itemPath, 'plugin.js'), { name: 'plugin.js' });
|
|
379
445
|
await arch.finalize();
|
|
380
446
|
catalog.push({ ...manifest, url: `${distUrl}/${bundleName}` });
|
|
381
|
-
console.log(`✓ Bundled ${manifest.
|
|
447
|
+
console.log(`✓ Bundled ${manifest.packageName}`);
|
|
382
448
|
}
|
|
383
449
|
}
|
|
384
450
|
const finalRepo = {
|