@streamerly/cli 0.0.1

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.
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
Binary file
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,322 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const commander_1 = require("commander");
41
+ const child_process_1 = require("child_process");
42
+ const fs = __importStar(require("fs"));
43
+ const path = __importStar(require("path"));
44
+ const adm_zip_1 = __importDefault(require("adm-zip"));
45
+ const glob_1 = __importDefault(require("glob"));
46
+ const axios_1 = __importDefault(require("axios"));
47
+ const form_data_1 = __importDefault(require("form-data"));
48
+ const archiver_1 = __importDefault(require("archiver"));
49
+ const program = new commander_1.Command();
50
+ /**
51
+ * Helper zum Ausführen eines Kommandos (z.B. npx tsc ...)
52
+ */
53
+ function run(cmd, args = []) {
54
+ return new Promise((resolve, reject) => {
55
+ const child = (0, child_process_1.spawn)(cmd, args, {
56
+ cwd: process.cwd(),
57
+ stdio: "inherit",
58
+ shell: process.platform === "win32",
59
+ });
60
+ child.on("error", (err) => reject(err));
61
+ child.on("close", (code) => {
62
+ if (code !== 0) {
63
+ return reject(new Error(`${cmd} exited with code ${code}`));
64
+ }
65
+ resolve();
66
+ });
67
+ });
68
+ }
69
+ /**
70
+ * streamerly create <name>
71
+ */
72
+ program
73
+ .command("create <name>")
74
+ .description("Create plugin from template")
75
+ .action(async (name) => {
76
+ const cwd = process.cwd();
77
+ // template.zip liegt beim CLI (in dist)
78
+ const templateZipPath = path.resolve(__dirname, "template.zip");
79
+ console.info("zip path", templateZipPath);
80
+ if (!fs.existsSync(templateZipPath)) {
81
+ console.error("❌ template.zip nicht gefunden:", templateZipPath);
82
+ process.exit(1);
83
+ }
84
+ // Zielordner im aktuellen Projekt
85
+ const targetDir = path.join(cwd, name);
86
+ if (fs.existsSync(targetDir)) {
87
+ console.error(`❌ Ordner "${name}" existiert bereits!`);
88
+ process.exit(1);
89
+ }
90
+ fs.mkdirSync(targetDir);
91
+ console.log(`📁 Ordner erstellt: ${targetDir}`);
92
+ console.log("➡️ Template entpacken…");
93
+ const zip = new adm_zip_1.default(templateZipPath);
94
+ zip.extractAllTo(targetDir, true);
95
+ console.log("✔️ Entpackt.");
96
+ console.log(`➡️ Ersetze "MyProject" → "${name}"`);
97
+ const files = glob_1.default.sync("**/*", {
98
+ cwd: targetDir,
99
+ nodir: true,
100
+ ignore: ["**/node_modules/**", "**/.git/**", "**/dist/**"],
101
+ });
102
+ for (const file of files) {
103
+ const abs = path.join(targetDir, file);
104
+ try {
105
+ let content = fs.readFileSync(abs, "utf8");
106
+ if (content.includes("MyProject")) {
107
+ content = content.replace(/MyProject/g, name);
108
+ fs.writeFileSync(abs, content);
109
+ }
110
+ }
111
+ catch {
112
+ // Binärdateien / nicht-Text ignorieren
113
+ }
114
+ }
115
+ console.log("✔️ Done!");
116
+ console.log(`🚀 Plugin erstellt in: ${targetDir}`);
117
+ });
118
+ /**
119
+ * streamerly build
120
+ * -> tsc -p tsconfig.json im aktuellen Projekt
121
+ */
122
+ program
123
+ .command("build")
124
+ .description("build plugin (tsc -p tsconfig.json)")
125
+ .action(async () => {
126
+ var _a;
127
+ try {
128
+ console.log("🏗 Building (tsc -p tsconfig.json) …");
129
+ await run("npx", ["tsc", "-p", "tsconfig.json"]);
130
+ console.log("✅ Build completed");
131
+ }
132
+ catch (err) {
133
+ console.error("❌ Build failed:", (_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err);
134
+ process.exit(1);
135
+ }
136
+ });
137
+ /**
138
+ * streamerly pack
139
+ * -> ./dist im aktuellen Projekt als plugin.zip packen
140
+ */
141
+ program
142
+ .command("pack")
143
+ .description("pack plugin (zip ./dist -> plugin.zip)")
144
+ .action(async () => {
145
+ const cwd = process.cwd();
146
+ const distDir = path.resolve(cwd, "dist");
147
+ const zipPath = path.resolve(cwd, "plugin.zip");
148
+ if (!fs.existsSync(distDir)) {
149
+ console.error("❌ dist Ordner nicht gefunden:", distDir);
150
+ process.exit(1);
151
+ }
152
+ console.log("📦 Packe dist → plugin.zip");
153
+ console.log(" dist:", distDir);
154
+ console.log(" zip :", zipPath);
155
+ await new Promise((resolve, reject) => {
156
+ const output = fs.createWriteStream(zipPath);
157
+ const archive = (0, archiver_1.default)("zip", { zlib: { level: 9 } });
158
+ output.on("close", () => {
159
+ console.log(`✅ plugin.zip erstellt (${archive.pointer()} bytes)`);
160
+ resolve();
161
+ });
162
+ output.on("error", (err) => {
163
+ reject(err);
164
+ });
165
+ archive.on("error", (err) => {
166
+ reject(err);
167
+ });
168
+ archive.pipe(output);
169
+ archive.directory(distDir, false);
170
+ archive.finalize();
171
+ });
172
+ });
173
+ /**
174
+ * streamerly start
175
+ * -> start dev servcer
176
+ */
177
+ program
178
+ .command("start")
179
+ .description("start the electron server")
180
+ .action(async () => {
181
+ var _a;
182
+ const cwd = process.cwd();
183
+ const streamerlyDir = path.resolve(cwd, ".streamerly");
184
+ const electronZipPath = path.resolve(__dirname, "electron.zip");
185
+ const exists = fs.existsSync(streamerlyDir);
186
+ if (!exists) {
187
+ console.log("🆕 Kein .streamerly-Verzeichnis gefunden, erstelle Setup …");
188
+ if (!fs.existsSync(electronZipPath)) {
189
+ console.error("❌ electron.zip nicht gefunden:", electronZipPath);
190
+ console.error("Stelle sicher, dass dein CLI-Build electron.zip in dist enthält.");
191
+ process.exit(1);
192
+ }
193
+ fs.mkdirSync(streamerlyDir, { recursive: true });
194
+ console.log(`📁 .streamerly erstellt: ${streamerlyDir}`);
195
+ console.log("➡️ Entpacke electron.zip …");
196
+ const zip = new adm_zip_1.default(electronZipPath);
197
+ zip.extractAllTo(streamerlyDir, true);
198
+ console.log("✔️ electron.zip entpackt.");
199
+ const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
200
+ await new Promise((resolve, reject) => {
201
+ const child = (0, child_process_1.spawn)(npmCmd, ["install"], {
202
+ cwd: streamerlyDir,
203
+ stdio: "inherit",
204
+ shell: process.platform === "win32",
205
+ });
206
+ child.on("error", reject);
207
+ child.on("close", (code) => {
208
+ if (code !== 0) {
209
+ return reject(new Error(`npm install exited with code ${code}`));
210
+ }
211
+ resolve();
212
+ });
213
+ });
214
+ console.log("✔️ npm install.");
215
+ }
216
+ else {
217
+ console.log("✅ .streamerly existiert bereits, überspringe Setup.");
218
+ }
219
+ // Dependencies checken / installieren
220
+ const nodeModulesDir = path.join(streamerlyDir, "node_modules");
221
+ const electronModuleDir = path.join(nodeModulesDir, "electron");
222
+ const hasNodeModules = fs.existsSync(nodeModulesDir);
223
+ const hasElectron = fs.existsSync(electronModuleDir);
224
+ const hasPackageJson = fs.existsSync(path.join(streamerlyDir, "package.json"));
225
+ try {
226
+ if (!hasNodeModules || !hasElectron) {
227
+ console.log("📦 Installiere Abhängigkeiten im .streamerly-Verzeichnis …");
228
+ // wenn ein package.json vorhanden ist: normal npm install
229
+ // sonst fallback: nur electron installieren
230
+ const installCmd = process.platform === "win32" ? "npm.cmd" : "npm";
231
+ const installArgs = hasPackageJson
232
+ ? ["install"]
233
+ : ["install", "electron"];
234
+ await new Promise((resolve, reject) => {
235
+ const child = (0, child_process_1.spawn)(installCmd, installArgs, {
236
+ cwd: streamerlyDir,
237
+ stdio: "inherit",
238
+ shell: process.platform === "win32",
239
+ });
240
+ child.on("error", reject);
241
+ child.on("close", (code) => {
242
+ if (code !== 0) {
243
+ return reject(new Error(`npm ${installArgs.join(" ")} exited with code ${code}`));
244
+ }
245
+ resolve();
246
+ });
247
+ });
248
+ console.log("✅ Dependencies installiert.");
249
+ }
250
+ else {
251
+ console.log("✅ Dependencies bereits vorhanden, überspringe npm install.");
252
+ }
253
+ }
254
+ catch (err) {
255
+ console.error("❌ Dependency-Installation fehlgeschlagen:", (_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err);
256
+ process.exit(1);
257
+ }
258
+ // Electron starten
259
+ console.log("🚀 Starte Electron Dev Server …");
260
+ const npxCmd = process.platform === "win32" ? "npx.cmd" : "npx";
261
+ // wir geben das Promise nicht zurück, sondern lassen den Prozess laufen
262
+ const child = (0, child_process_1.spawn)(npxCmd, ["electron", "index.js"], {
263
+ cwd: streamerlyDir,
264
+ stdio: "inherit",
265
+ shell: process.platform === "win32",
266
+ env: {
267
+ ...process.env,
268
+ PLUGIN: "1"
269
+ }
270
+ });
271
+ child.on("close", (code) => {
272
+ if (code !== 0) {
273
+ console.error(`❌ Electron beendet mit Exit-Code ${code}`);
274
+ process.exit(code !== null && code !== void 0 ? code : 1);
275
+ }
276
+ else {
277
+ console.log("👋 Electron beendet.");
278
+ }
279
+ });
280
+ });
281
+ /**
282
+ * streamerly deploy
283
+ * -> plugin.zip aus aktuellem Projekt zu deinem Backend hochladen
284
+ */
285
+ program
286
+ .command("deploy")
287
+ .description("deploy plugin (upload plugin.zip)")
288
+ .action(async () => {
289
+ var _a;
290
+ const cwd = process.cwd();
291
+ const zipPath = path.resolve(cwd, "plugin.zip");
292
+ if (!fs.existsSync(zipPath)) {
293
+ console.error("❌ plugin.zip nicht gefunden:", zipPath);
294
+ console.error("Tipp: erst `streamerly pack` ausführen.");
295
+ process.exit(1);
296
+ }
297
+ console.log("🚀 Deploy plugin:", zipPath);
298
+ const form = new form_data_1.default();
299
+ form.append("file", fs.createReadStream(zipPath), "plugin.zip");
300
+ try {
301
+ const res = await axios_1.default.post("http://localhost:8090/plugin/deploy", form, {
302
+ headers: {
303
+ ...form.getHeaders(),
304
+ },
305
+ maxBodyLength: Infinity,
306
+ });
307
+ console.log("✅ Upload erfolgreich:", res.status, res.statusText);
308
+ console.log(res.data);
309
+ }
310
+ catch (err) {
311
+ console.error("❌ Upload fehlgeschlagen");
312
+ if (err.response) {
313
+ console.error("Status:", err.response.status);
314
+ console.error("Body:", err.response.data);
315
+ }
316
+ else {
317
+ console.error((_a = err.message) !== null && _a !== void 0 ? _a : err);
318
+ }
319
+ process.exit(1);
320
+ }
321
+ });
322
+ program.parse();
Binary file
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@streamerly/cli",
3
+ "version": "0.0.1",
4
+ "bin": {
5
+ "streamerly": "dist/index.js"
6
+ },
7
+ "license": "MIT",
8
+ "scripts": {
9
+ "build": "tsc -p tsconfig.json && npm run buildElectron && npm run packElectron && npm run packPlugin",
10
+ "buildElectron": "npm install --prefix ../../electron && npm run build --prefix ../../electron",
11
+ "packElectron": "node zipElectron.js",
12
+ "packPlugin": "node zipPlugin.js"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "devDependencies": {
18
+ "@types/adm-zip": "^0.5.7",
19
+ "@types/archiver": "^7.0.0",
20
+ "typescript": "^5.0.0",
21
+ "zip-cli": "^0.0.0"
22
+ },
23
+ "dependencies": {
24
+ "adm-zip": "^0.5.16",
25
+ "archiver": "^7.0.1",
26
+ "axios": "^1.13.2",
27
+ "commander": "^14.0.2",
28
+ "form-data": "^4.0.5",
29
+ "glob": "^13.0.0"
30
+ }
31
+ }
package/src/actions.ts ADDED
File without changes
package/src/index.ts ADDED
@@ -0,0 +1,334 @@
1
+ #!/usr/bin/env node
2
+ import {Command} from "commander";
3
+ import {spawn} from "child_process";
4
+ import * as fs from "fs";
5
+ import * as path from "path";
6
+ import AdmZip from "adm-zip";
7
+ import glob from "glob";
8
+ import axios from "axios";
9
+ import FormData from "form-data";
10
+ import archiver from "archiver";
11
+
12
+ const program = new Command();
13
+
14
+ /**
15
+ * Helper zum Ausführen eines Kommandos (z.B. npx tsc ...)
16
+ */
17
+ function run(cmd: string, args: string[] = []): Promise<void> {
18
+ return new Promise((resolve, reject) => {
19
+ const child = spawn(cmd, args, {
20
+ cwd: process.cwd(),
21
+ stdio: "inherit",
22
+ shell: process.platform === "win32",
23
+ });
24
+
25
+ child.on("error", (err) => reject(err));
26
+ child.on("close", (code) => {
27
+ if (code !== 0) {
28
+ return reject(new Error(`${cmd} exited with code ${code}`));
29
+ }
30
+ resolve();
31
+ });
32
+ });
33
+ }
34
+
35
+ /**
36
+ * streamerly create <name>
37
+ */
38
+ program
39
+ .command("create <name>")
40
+ .description("Create plugin from template")
41
+ .action(async (name: string) => {
42
+ const cwd = process.cwd();
43
+
44
+ // template.zip liegt beim CLI (in dist)
45
+ const templateZipPath = path.resolve(__dirname, "template.zip");
46
+ console.info("zip path", templateZipPath);
47
+
48
+ if (!fs.existsSync(templateZipPath)) {
49
+ console.error("❌ template.zip nicht gefunden:", templateZipPath);
50
+ process.exit(1);
51
+ }
52
+
53
+ // Zielordner im aktuellen Projekt
54
+ const targetDir = path.join(cwd, name);
55
+
56
+ if (fs.existsSync(targetDir)) {
57
+ console.error(`❌ Ordner "${name}" existiert bereits!`);
58
+ process.exit(1);
59
+ }
60
+
61
+ fs.mkdirSync(targetDir);
62
+
63
+ console.log(`📁 Ordner erstellt: ${targetDir}`);
64
+ console.log("➡️ Template entpacken…");
65
+
66
+ const zip = new AdmZip(templateZipPath);
67
+ zip.extractAllTo(targetDir, true);
68
+
69
+ console.log("✔️ Entpackt.");
70
+ console.log(`➡️ Ersetze "MyProject" → "${name}"`);
71
+
72
+ const files = glob.sync("**/*", {
73
+ cwd: targetDir,
74
+ nodir: true,
75
+ ignore: ["**/node_modules/**", "**/.git/**", "**/dist/**"],
76
+ });
77
+
78
+ for (const file of files) {
79
+ const abs = path.join(targetDir, file);
80
+
81
+ try {
82
+ let content = fs.readFileSync(abs, "utf8");
83
+
84
+ if (content.includes("MyProject")) {
85
+ content = content.replace(/MyProject/g, name);
86
+ fs.writeFileSync(abs, content);
87
+ }
88
+ } catch {
89
+ // Binärdateien / nicht-Text ignorieren
90
+ }
91
+ }
92
+
93
+ console.log("✔️ Done!");
94
+ console.log(`🚀 Plugin erstellt in: ${targetDir}`);
95
+ });
96
+
97
+ /**
98
+ * streamerly build
99
+ * -> tsc -p tsconfig.json im aktuellen Projekt
100
+ */
101
+ program
102
+ .command("build")
103
+ .description("build plugin (tsc -p tsconfig.json)")
104
+ .action(async () => {
105
+ try {
106
+ console.log("🏗 Building (tsc -p tsconfig.json) …");
107
+ await run("npx", ["tsc", "-p", "tsconfig.json"]);
108
+ console.log("✅ Build completed");
109
+ } catch (err: any) {
110
+ console.error("❌ Build failed:", err?.message ?? err);
111
+ process.exit(1);
112
+ }
113
+ });
114
+
115
+ /**
116
+ * streamerly pack
117
+ * -> ./dist im aktuellen Projekt als plugin.zip packen
118
+ */
119
+ program
120
+ .command("pack")
121
+ .description("pack plugin (zip ./dist -> plugin.zip)")
122
+ .action(async () => {
123
+ const cwd = process.cwd();
124
+ const distDir = path.resolve(cwd, "dist");
125
+ const zipPath = path.resolve(cwd, "plugin.zip");
126
+
127
+ if (!fs.existsSync(distDir)) {
128
+ console.error("❌ dist Ordner nicht gefunden:", distDir);
129
+ process.exit(1);
130
+ }
131
+
132
+ console.log("📦 Packe dist → plugin.zip");
133
+ console.log(" dist:", distDir);
134
+ console.log(" zip :", zipPath);
135
+
136
+ await new Promise<void>((resolve, reject) => {
137
+ const output = fs.createWriteStream(zipPath);
138
+ const archive = archiver("zip", {zlib: {level: 9}});
139
+
140
+ output.on("close", () => {
141
+ console.log(`✅ plugin.zip erstellt (${archive.pointer()} bytes)`);
142
+ resolve();
143
+ });
144
+
145
+ output.on("error", (err) => {
146
+ reject(err);
147
+ });
148
+
149
+ archive.on("error", (err: any) => {
150
+ reject(err);
151
+ });
152
+
153
+ archive.pipe(output);
154
+ archive.directory(distDir, false);
155
+ archive.finalize();
156
+ });
157
+ });
158
+
159
+ /**
160
+ * streamerly start
161
+ * -> start dev servcer
162
+ */
163
+ program
164
+ .command("start")
165
+ .description("start the electron server")
166
+ .action(async () => {
167
+ const cwd = process.cwd();
168
+ const streamerlyDir = path.resolve(cwd, ".streamerly");
169
+ const electronZipPath = path.resolve(__dirname, "electron.zip");
170
+
171
+ const exists = fs.existsSync(streamerlyDir);
172
+
173
+ if (!exists) {
174
+ console.log("🆕 Kein .streamerly-Verzeichnis gefunden, erstelle Setup …");
175
+
176
+ if (!fs.existsSync(electronZipPath)) {
177
+ console.error("❌ electron.zip nicht gefunden:", electronZipPath);
178
+ console.error("Stelle sicher, dass dein CLI-Build electron.zip in dist enthält.");
179
+ process.exit(1);
180
+ }
181
+
182
+ fs.mkdirSync(streamerlyDir, {recursive: true});
183
+
184
+ console.log(`📁 .streamerly erstellt: ${streamerlyDir}`);
185
+ console.log("➡️ Entpacke electron.zip …");
186
+
187
+ const zip = new AdmZip(electronZipPath);
188
+ zip.extractAllTo(streamerlyDir, true);
189
+
190
+ console.log("✔️ electron.zip entpackt.");
191
+
192
+ const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
193
+
194
+ await new Promise<void>((resolve, reject) => {
195
+ const child = spawn(npmCmd, ["install"], {
196
+ cwd: streamerlyDir,
197
+ stdio: "inherit",
198
+ shell: process.platform === "win32",
199
+ });
200
+
201
+ child.on("error", reject);
202
+ child.on("close", (code) => {
203
+ if (code !== 0) {
204
+ return reject(new Error(`npm install exited with code ${code}`));
205
+ }
206
+ resolve();
207
+ });
208
+ });
209
+
210
+ console.log("✔️ npm install.");
211
+ } else {
212
+ console.log("✅ .streamerly existiert bereits, überspringe Setup.");
213
+ }
214
+
215
+ // Dependencies checken / installieren
216
+ const nodeModulesDir = path.join(streamerlyDir, "node_modules");
217
+ const electronModuleDir = path.join(nodeModulesDir, "electron");
218
+ const hasNodeModules = fs.existsSync(nodeModulesDir);
219
+ const hasElectron = fs.existsSync(electronModuleDir);
220
+ const hasPackageJson = fs.existsSync(path.join(streamerlyDir, "package.json"));
221
+
222
+ try {
223
+ if (!hasNodeModules || !hasElectron) {
224
+ console.log("📦 Installiere Abhängigkeiten im .streamerly-Verzeichnis …");
225
+
226
+ // wenn ein package.json vorhanden ist: normal npm install
227
+ // sonst fallback: nur electron installieren
228
+ const installCmd = process.platform === "win32" ? "npm.cmd" : "npm";
229
+
230
+ const installArgs = hasPackageJson
231
+ ? ["install"]
232
+ : ["install", "electron"];
233
+
234
+ await new Promise<void>((resolve, reject) => {
235
+ const child = spawn(installCmd, installArgs, {
236
+ cwd: streamerlyDir,
237
+ stdio: "inherit",
238
+ shell: process.platform === "win32",
239
+ });
240
+
241
+ child.on("error", reject);
242
+ child.on("close", (code) => {
243
+ if (code !== 0) {
244
+ return reject(new Error(`npm ${installArgs.join(" ")} exited with code ${code}`));
245
+ }
246
+ resolve();
247
+ });
248
+ });
249
+
250
+ console.log("✅ Dependencies installiert.");
251
+ } else {
252
+ console.log("✅ Dependencies bereits vorhanden, überspringe npm install.");
253
+ }
254
+ } catch (err: any) {
255
+ console.error("❌ Dependency-Installation fehlgeschlagen:", err?.message ?? err);
256
+ process.exit(1);
257
+ }
258
+
259
+ // Electron starten
260
+ console.log("🚀 Starte Electron Dev Server …");
261
+
262
+ const npxCmd = process.platform === "win32" ? "npx.cmd" : "npx";
263
+
264
+ // wir geben das Promise nicht zurück, sondern lassen den Prozess laufen
265
+ const child = spawn(
266
+ npxCmd,
267
+ ["electron", "index.js"],
268
+ {
269
+ cwd: streamerlyDir,
270
+ stdio: "inherit",
271
+ shell: process.platform === "win32",
272
+
273
+ env: {
274
+ ...process.env,
275
+ PLUGIN: "1"
276
+ }
277
+ }
278
+ );
279
+
280
+ child.on("close", (code) => {
281
+ if (code !== 0) {
282
+ console.error(`❌ Electron beendet mit Exit-Code ${code}`);
283
+ process.exit(code ?? 1);
284
+ } else {
285
+ console.log("👋 Electron beendet.");
286
+ }
287
+ });
288
+ });
289
+
290
+ /**
291
+ * streamerly deploy
292
+ * -> plugin.zip aus aktuellem Projekt zu deinem Backend hochladen
293
+ */
294
+ program
295
+ .command("deploy")
296
+ .description("deploy plugin (upload plugin.zip)")
297
+ .action(async () => {
298
+ const cwd = process.cwd();
299
+ const zipPath = path.resolve(cwd, "plugin.zip");
300
+
301
+ if (!fs.existsSync(zipPath)) {
302
+ console.error("❌ plugin.zip nicht gefunden:", zipPath);
303
+ console.error("Tipp: erst `streamerly pack` ausführen.");
304
+ process.exit(1);
305
+ }
306
+
307
+ console.log("🚀 Deploy plugin:", zipPath);
308
+
309
+ const form = new FormData();
310
+ form.append("file", fs.createReadStream(zipPath), "plugin.zip");
311
+
312
+ try {
313
+ const res = await axios.post("http://localhost:8090/plugin/deploy", form, {
314
+ headers: {
315
+ ...form.getHeaders(),
316
+ },
317
+ maxBodyLength: Infinity,
318
+ });
319
+
320
+ console.log("✅ Upload erfolgreich:", res.status, res.statusText);
321
+ console.log(res.data);
322
+ } catch (err: any) {
323
+ console.error("❌ Upload fehlgeschlagen");
324
+ if (err.response) {
325
+ console.error("Status:", err.response.status);
326
+ console.error("Body:", err.response.data);
327
+ } else {
328
+ console.error(err.message ?? err);
329
+ }
330
+ process.exit(1);
331
+ }
332
+ });
333
+
334
+ program.parse();
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "rootDir": "src",
5
+ "outDir": "dist"
6
+ },
7
+ "include": [
8
+ "src"
9
+ ]
10
+ }
package/zipElectron.js ADDED
@@ -0,0 +1,12 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const archiver = require("archiver");
4
+
5
+ const electronDir = path.resolve(__dirname, "../../", "electron", "./dist");
6
+ const output = fs.createWriteStream(path.resolve(__dirname, "./dist/electron.zip"));
7
+
8
+ const archive = archiver("zip", {zlib: {level: 9}});
9
+
10
+ archive.pipe(output);
11
+ archive.directory(electronDir, false);
12
+ archive.finalize();
package/zipPlugin.js ADDED
@@ -0,0 +1,22 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+ const archiver = require("archiver");
4
+
5
+ const pluginDir = path.resolve(__dirname, "../../", "plugin");
6
+ const output = fs.createWriteStream(path.resolve(__dirname, "./dist/template.zip"));
7
+
8
+ const archive = archiver("zip", {zlib: {level: 9}});
9
+
10
+ archive.pipe(output);
11
+ archive.glob("**/*", {
12
+ cwd: pluginDir,
13
+ dot: true,
14
+ nodir: true,
15
+ follow: false,
16
+ ignore: [
17
+ "**/node_modules/**",
18
+ "**/dist/**",
19
+ "**/plugin.zip"
20
+ ]
21
+ });
22
+ archive.finalize();