code-mon-config 1.0.7 ā 1.0.9
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/index.js +258 -64
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -9,6 +9,7 @@ const open = require("open");
|
|
|
9
9
|
const WebSocket = require("ws");
|
|
10
10
|
|
|
11
11
|
const app = express();
|
|
12
|
+
|
|
12
13
|
app.use(cors());
|
|
13
14
|
app.use(express.json());
|
|
14
15
|
|
|
@@ -16,162 +17,355 @@ const PORT = 3000;
|
|
|
16
17
|
const ROOT = process.cwd();
|
|
17
18
|
|
|
18
19
|
/* ---------------- PROCESS MANAGER ---------------- */
|
|
20
|
+
|
|
19
21
|
let processes = {};
|
|
20
22
|
let processId = 0;
|
|
21
23
|
|
|
24
|
+
/* ---------------- SAFE PATH ---------------- */
|
|
25
|
+
|
|
26
|
+
function safePath(filename) {
|
|
27
|
+
|
|
28
|
+
if (!filename) {
|
|
29
|
+
throw new Error("Filename required");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const resolved = path.join(ROOT, filename);
|
|
33
|
+
|
|
34
|
+
if (!resolved.startsWith(ROOT)) {
|
|
35
|
+
throw new Error("Invalid path");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return resolved;
|
|
39
|
+
}
|
|
40
|
+
|
|
22
41
|
/* ---------------- FILE TREE ---------------- */
|
|
42
|
+
|
|
23
43
|
function getTree(dir, base = "") {
|
|
44
|
+
|
|
24
45
|
let results = [];
|
|
25
46
|
const list = fs.readdirSync(dir);
|
|
26
47
|
|
|
27
48
|
list.forEach(file => {
|
|
49
|
+
|
|
28
50
|
const full = path.join(dir, file);
|
|
29
51
|
const rel = path.join(base, file);
|
|
30
52
|
const stat = fs.statSync(full);
|
|
31
53
|
|
|
32
54
|
if (stat.isDirectory()) {
|
|
55
|
+
|
|
33
56
|
results.push(rel + "/");
|
|
34
57
|
results = results.concat(getTree(full, rel));
|
|
58
|
+
|
|
35
59
|
} else {
|
|
60
|
+
|
|
36
61
|
results.push(rel);
|
|
62
|
+
|
|
37
63
|
}
|
|
64
|
+
|
|
38
65
|
});
|
|
39
66
|
|
|
40
67
|
return results;
|
|
41
68
|
}
|
|
42
69
|
|
|
43
70
|
/* ---------------- FILE APIs ---------------- */
|
|
71
|
+
|
|
44
72
|
app.get("/list", (req, res) => {
|
|
73
|
+
|
|
45
74
|
try {
|
|
75
|
+
|
|
46
76
|
const tree = getTree(ROOT);
|
|
47
|
-
|
|
77
|
+
|
|
78
|
+
res.json({
|
|
79
|
+
root: ROOT,
|
|
80
|
+
files: tree
|
|
81
|
+
});
|
|
82
|
+
|
|
48
83
|
} catch (err) {
|
|
84
|
+
|
|
49
85
|
res.json({ error: err.message });
|
|
86
|
+
|
|
50
87
|
}
|
|
88
|
+
|
|
51
89
|
});
|
|
52
90
|
|
|
91
|
+
/* LOAD FILE */
|
|
92
|
+
|
|
53
93
|
app.get("/load", (req, res) => {
|
|
54
|
-
const filename = req.query.filename;
|
|
55
|
-
const filePath = path.join(ROOT, filename);
|
|
56
94
|
|
|
57
|
-
|
|
95
|
+
try {
|
|
96
|
+
|
|
97
|
+
const filename = req.query.filename;
|
|
98
|
+
const filePath = safePath(filename);
|
|
99
|
+
|
|
100
|
+
if (!fs.existsSync(filePath)) {
|
|
101
|
+
return res.json({ error: "File not found" });
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
105
|
+
|
|
106
|
+
res.json({ content });
|
|
107
|
+
|
|
108
|
+
} catch (err) {
|
|
109
|
+
|
|
110
|
+
res.json({ error: err.message });
|
|
111
|
+
|
|
112
|
+
}
|
|
58
113
|
|
|
59
|
-
const content = fs.readFileSync(filePath, "utf8");
|
|
60
|
-
res.json({ content });
|
|
61
114
|
});
|
|
62
115
|
|
|
116
|
+
/* SAVE FILE */
|
|
117
|
+
|
|
63
118
|
app.post("/save", (req, res) => {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
|
|
122
|
+
const { filename, content } = req.body;
|
|
123
|
+
|
|
124
|
+
const filePath = safePath(filename);
|
|
125
|
+
|
|
126
|
+
fs.writeFileSync(filePath, content || "");
|
|
127
|
+
|
|
128
|
+
res.json({ success: true });
|
|
129
|
+
|
|
130
|
+
} catch (err) {
|
|
131
|
+
|
|
132
|
+
res.json({ error: err.message });
|
|
133
|
+
|
|
134
|
+
}
|
|
135
|
+
|
|
68
136
|
});
|
|
69
137
|
|
|
138
|
+
/* CREATE FILE */
|
|
139
|
+
|
|
70
140
|
app.post("/create", (req, res) => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
|
|
144
|
+
const { filename } = req.body;
|
|
145
|
+
|
|
146
|
+
const filePath = safePath(filename);
|
|
147
|
+
|
|
148
|
+
fs.writeFileSync(filePath, "");
|
|
149
|
+
|
|
150
|
+
res.json({ success: true });
|
|
151
|
+
|
|
152
|
+
} catch (err) {
|
|
153
|
+
|
|
154
|
+
res.json({ error: err.message });
|
|
155
|
+
|
|
156
|
+
}
|
|
157
|
+
|
|
75
158
|
});
|
|
76
159
|
|
|
160
|
+
/* DELETE FILE */
|
|
161
|
+
|
|
77
162
|
app.delete("/delete", (req, res) => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
163
|
+
|
|
164
|
+
try {
|
|
165
|
+
|
|
166
|
+
const { filename } = req.body;
|
|
167
|
+
|
|
168
|
+
const filePath = safePath(filename);
|
|
169
|
+
|
|
170
|
+
if (fs.existsSync(filePath)) {
|
|
171
|
+
fs.unlinkSync(filePath);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
res.json({ success: true });
|
|
175
|
+
|
|
176
|
+
} catch (err) {
|
|
177
|
+
|
|
178
|
+
res.json({ error: err.message });
|
|
179
|
+
|
|
180
|
+
}
|
|
181
|
+
|
|
82
182
|
});
|
|
83
183
|
|
|
84
|
-
/* ---------------- EXECUTE COMMAND ---------------- */
|
|
184
|
+
/* ---------------- EXECUTE COMMAND (FIXED) ---------------- */
|
|
185
|
+
|
|
85
186
|
app.post("/execute", (req, res) => {
|
|
86
|
-
const { command } = req.body;
|
|
87
|
-
if (!command) return res.json({ error: "Command required" });
|
|
88
187
|
|
|
89
|
-
|
|
90
|
-
const proc = spawn(parts[0], parts.slice(1), { cwd: ROOT, shell: true });
|
|
91
|
-
const id = processId++;
|
|
92
|
-
processes[id] = proc;
|
|
188
|
+
try {
|
|
93
189
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
190
|
+
const { command } = req.body;
|
|
191
|
+
|
|
192
|
+
if (!command) {
|
|
193
|
+
return res.json({ error: "Command required" });
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const proc = spawn(command, {
|
|
197
|
+
cwd: ROOT,
|
|
198
|
+
shell: true
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
const id = processId++;
|
|
202
|
+
|
|
203
|
+
processes[id] = proc;
|
|
204
|
+
|
|
205
|
+
let output = "";
|
|
206
|
+
let error = "";
|
|
207
|
+
|
|
208
|
+
proc.stdout.on("data", data => {
|
|
209
|
+
output += data.toString();
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
proc.stderr.on("data", data => {
|
|
213
|
+
error += data.toString();
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
proc.on("close", code => {
|
|
217
|
+
|
|
218
|
+
delete processes[id];
|
|
219
|
+
|
|
220
|
+
res.json({
|
|
221
|
+
success: true,
|
|
222
|
+
processId: id,
|
|
223
|
+
code: code,
|
|
224
|
+
output: output,
|
|
225
|
+
error: error
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
} catch (err) {
|
|
231
|
+
|
|
232
|
+
res.json({ error: err.message });
|
|
233
|
+
|
|
234
|
+
}
|
|
100
235
|
|
|
101
|
-
res.json({ success: true, processId: id });
|
|
102
236
|
});
|
|
103
237
|
|
|
104
238
|
/* ---------------- PROCESS LIST ---------------- */
|
|
239
|
+
|
|
105
240
|
app.get("/processes", (req, res) => {
|
|
106
|
-
|
|
241
|
+
|
|
242
|
+
const list = Object.keys(processes).map(id => ({
|
|
243
|
+
id
|
|
244
|
+
}));
|
|
245
|
+
|
|
107
246
|
res.json(list);
|
|
247
|
+
|
|
108
248
|
});
|
|
109
249
|
|
|
110
250
|
/* ---------------- STOP PROCESS ---------------- */
|
|
251
|
+
|
|
111
252
|
app.post("/stop-process", (req, res) => {
|
|
112
|
-
const { id } = req.body;
|
|
113
|
-
if (!processes[id]) return res.json({ error: "Process not found" });
|
|
114
253
|
|
|
115
|
-
|
|
116
|
-
|
|
254
|
+
try {
|
|
255
|
+
|
|
256
|
+
const { id } = req.body;
|
|
257
|
+
|
|
258
|
+
if (!processes[id]) {
|
|
259
|
+
return res.json({ error: "Process not found" });
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
processes[id].kill();
|
|
263
|
+
|
|
264
|
+
delete processes[id];
|
|
265
|
+
|
|
266
|
+
res.json({
|
|
267
|
+
success: true,
|
|
268
|
+
message: "Process stopped"
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
} catch (err) {
|
|
272
|
+
|
|
273
|
+
res.json({ error: err.message });
|
|
274
|
+
|
|
275
|
+
}
|
|
117
276
|
|
|
118
|
-
res.json({ success: true, message: "Process stopped" });
|
|
119
277
|
});
|
|
120
278
|
|
|
121
279
|
/* ---------------- EXTENSION LOADER ---------------- */
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
280
|
+
|
|
281
|
+
const EXTENSIONS_DIR = path.join(ROOT, "extensions");
|
|
282
|
+
|
|
283
|
+
if (fs.existsSync(EXTENSIONS_DIR)) {
|
|
284
|
+
|
|
285
|
+
fs.readdirSync(EXTENSIONS_DIR).forEach(file => {
|
|
286
|
+
|
|
125
287
|
if (file.endsWith(".js")) {
|
|
288
|
+
|
|
126
289
|
try {
|
|
127
|
-
|
|
290
|
+
|
|
291
|
+
require(path.join(EXTENSIONS_DIR, file))({
|
|
292
|
+
app,
|
|
293
|
+
ROOT,
|
|
294
|
+
spawn,
|
|
295
|
+
processes
|
|
296
|
+
});
|
|
297
|
+
|
|
128
298
|
console.log(`š Loaded extension: ${file}`);
|
|
129
|
-
|
|
130
|
-
|
|
299
|
+
|
|
300
|
+
} catch (err) {
|
|
301
|
+
|
|
302
|
+
console.log(`ā Failed to load extension: ${file}`);
|
|
303
|
+
|
|
131
304
|
}
|
|
305
|
+
|
|
132
306
|
}
|
|
307
|
+
|
|
133
308
|
});
|
|
309
|
+
|
|
134
310
|
}
|
|
135
311
|
|
|
136
312
|
/* ---------------- START SERVER ---------------- */
|
|
313
|
+
|
|
137
314
|
const server = app.listen(PORT, async () => {
|
|
138
|
-
|
|
315
|
+
|
|
316
|
+
console.log("\nš Code Mon Config Starting...\n");
|
|
317
|
+
|
|
139
318
|
console.log("š Connected Folder:", ROOT);
|
|
319
|
+
|
|
140
320
|
console.log("\nā
Your terminal has been connected with Code Mon Code Space\n");
|
|
141
321
|
|
|
142
|
-
const url =
|
|
322
|
+
const url = "http://localhost:3000";
|
|
323
|
+
|
|
143
324
|
console.log("š Opening:", url);
|
|
144
|
-
|
|
325
|
+
|
|
326
|
+
try {
|
|
327
|
+
|
|
328
|
+
await open(url);
|
|
329
|
+
|
|
330
|
+
} catch {
|
|
331
|
+
|
|
332
|
+
console.log("Open manually:", url);
|
|
333
|
+
|
|
334
|
+
}
|
|
335
|
+
|
|
145
336
|
});
|
|
146
337
|
|
|
147
|
-
/* ---------------- WEBSOCKET TERMINAL ---------------- */
|
|
338
|
+
/* ---------------- WEBSOCKET TERMINAL (FIXED) ---------------- */
|
|
339
|
+
|
|
148
340
|
const wss = new WebSocket.Server({ server });
|
|
149
341
|
|
|
150
342
|
wss.on("connection", ws => {
|
|
151
|
-
console.log("š¢ Terminal connected");
|
|
152
343
|
|
|
153
|
-
|
|
154
|
-
ws.on("message", msg => {
|
|
155
|
-
const command = msg.toString();
|
|
344
|
+
console.log("š¢ Terminal connected");
|
|
156
345
|
|
|
157
|
-
|
|
158
|
-
|
|
346
|
+
let shell = spawn(process.env.SHELL || "bash", [], {
|
|
347
|
+
cwd: ROOT,
|
|
348
|
+
shell: true
|
|
349
|
+
});
|
|
159
350
|
|
|
160
|
-
|
|
161
|
-
|
|
351
|
+
shell.stdout.on("data", data => {
|
|
352
|
+
ws.send(data.toString());
|
|
353
|
+
});
|
|
162
354
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
});
|
|
355
|
+
shell.stderr.on("data", data => {
|
|
356
|
+
ws.send(data.toString());
|
|
357
|
+
});
|
|
167
358
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
359
|
+
ws.on("message", msg => {
|
|
360
|
+
shell.stdin.write(msg.toString());
|
|
171
361
|
});
|
|
172
362
|
|
|
173
363
|
ws.on("close", () => {
|
|
174
|
-
|
|
364
|
+
|
|
365
|
+
shell.kill();
|
|
366
|
+
|
|
175
367
|
console.log("š“ Terminal disconnected");
|
|
368
|
+
|
|
176
369
|
});
|
|
370
|
+
|
|
177
371
|
});
|