@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.
- package/dist/actions.d.ts +0 -0
- package/dist/actions.js +1 -0
- package/dist/electron.zip +0 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +322 -0
- package/dist/template.zip +0 -0
- package/package.json +31 -0
- package/src/actions.ts +0 -0
- package/src/index.ts +334 -0
- package/tsconfig.json +10 -0
- package/zipElectron.js +12 -0
- package/zipPlugin.js +22 -0
|
File without changes
|
package/dist/actions.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
Binary file
|
package/dist/index.d.ts
ADDED
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
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();
|