Skip to content

Commit fc840e9

Browse files
committed
Remote Instance: support remote API server and ws server
1 parent 105894f commit fc840e9

File tree

10 files changed

+354
-79
lines changed

10 files changed

+354
-79
lines changed

desktop/main.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ async function handleListPathContent(event, uri, options) {
203203
return await listPathContent(uri, options);
204204
}
205205

206-
async function handleHasFile(event, path) {
206+
async function handleHasPath(event, path) {
207207
return fs.existsSync(path);
208208
}
209209

@@ -278,7 +278,7 @@ app.whenReady().then(() => {
278278
ipcMain.handle("rename", handleRename);
279279
ipcMain.handle("delete", handleDelete);
280280

281-
ipcMain.handle("has-file", handleHasFile);
281+
ipcMain.handle("has-path", handleHasPath);
282282
ipcMain.handle("read-file", handleReadFile);
283283
ipcMain.handle("write-file", handleWriteFile);
284284

desktop/preload.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ contextBridge.exposeInMainWorld("electronAPI", {
1616
rename: (oldUri, newUri) => ipcRenderer.invoke("rename", oldUri, newUri),
1717
delete: (uri) => ipcRenderer.invoke("delete", uri),
1818

19-
hasFile: (path) => ipcRenderer.invoke("has-file", path),
19+
hasPath: (path) => ipcRenderer.invoke("has-path", path),
2020
readFile: (path) => ipcRenderer.invoke("read-file", path),
2121
writeFile: (data, path) => ipcRenderer.invoke("write-file", data, path),
2222

remote-instance/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ Create `.env` file in current folder, and set `SSL_CERT_PATH` and `SSL_KEY_PATH`
2626
Generate self-signed SSL certificates:
2727

2828
```bash
29-
bash ./generate-self-signed.sh
29+
bash ./utils/generate-self-signed.sh
3030
```

remote-instance/package-lock.json

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

remote-instance/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
"start": "node dist/index.js"
1212
},
1313
"dependencies": {
14+
"@pulse-editor/shared-utils": "^0.1.1-alpha.24",
1415
"dotenv": "^17.2.0",
1516
"express": "^5.1.0",
17+
"ignore": "^7.0.5",
1618
"node-pty": "^1.1.0-beta34",
1719
"ws": "^8.18.3"
1820
},

remote-instance/src/index.ts

Lines changed: 6 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,8 @@
1-
import express from "express";
2-
import { createTerminalServer } from "./node-pty/node-pty-server";
3-
import https from "https";
4-
import http from "http";
5-
import fs from "fs";
6-
import dotenv from "dotenv";
1+
import { createTerminalServer } from "./servers/node-pty";
2+
import { createAPIServer } from "./servers/api-server";
73

8-
// Load environment variables from .env file
9-
dotenv.config();
10-
11-
const app = express();
12-
const HOST = "0.0.0.0";
13-
const HTTP_SERVER_PORT = 6080;
14-
const HTTPS_SERVER_PORT = 6443;
15-
16-
app.get("/:appname/", (_req, res) => {
17-
// Get the requested URL
18-
const serverUrl = _req.protocol + "://" + _req.get("host") + _req.originalUrl;
19-
20-
// Redirect to https://editor.pulse-editor.com and append
21-
// this instance's URL as a query parameter
22-
const url = new URL(
23-
process.env.FRONTEND_URL ?? "https://editor.pulse-editor.com"
24-
);
25-
url.searchParams.append("instance", serverUrl);
26-
res.redirect(url.toString());
27-
});
28-
29-
app.get("/:appname/test", (_req, res) => {
30-
res.send("Remote instance is running!");
31-
});
32-
33-
const certPath = process.env.SSL_CERT_PATH;
34-
const keyPath = process.env.SSL_KEY_PATH;
35-
36-
// Check if the certs directory exists
37-
if (
38-
!certPath ||
39-
!keyPath ||
40-
!fs.existsSync(certPath) ||
41-
!fs.existsSync(keyPath)
42-
) {
43-
console.log("SSL certificates not found. Using HTTP instead of HTTPS. ");
44-
45-
const server = http.createServer(app);
46-
47-
// Start the terminal websocket server
4+
/* Create servers */
5+
createAPIServer().then((server) => {
6+
// After API server is created, the terminal server can use it
487
createTerminalServer(server);
49-
50-
server.listen(HTTP_SERVER_PORT, HOST, () => {
51-
console.log(`HTTP server is running on port ${HTTP_SERVER_PORT}`);
52-
});
53-
} else {
54-
const server = https.createServer(
55-
{
56-
key: fs.readFileSync(keyPath),
57-
cert: fs.readFileSync(certPath),
58-
},
59-
app
60-
);
61-
62-
// Start the terminal websocket server
63-
createTerminalServer(server);
64-
65-
server.listen(HTTPS_SERVER_PORT, HOST, () => {
66-
console.log(`HTTPS server is running on port ${HTTPS_SERVER_PORT}`);
67-
});
68-
}
8+
});
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import express from "express";
2+
import https from "https";
3+
import http from "http";
4+
import fs from "fs";
5+
import dotenv from "dotenv";
6+
import { handlePlatformAPIRequest } from "./platform-api/handler";
7+
8+
dotenv.config();
9+
10+
const app = express();
11+
const HOST = "0.0.0.0";
12+
const HTTP_SERVER_PORT = 6080;
13+
const HTTPS_SERVER_PORT = 6443;
14+
const certPath = process.env.SSL_CERT_PATH;
15+
const keyPath = process.env.SSL_KEY_PATH;
16+
17+
export async function createAPIServer() {
18+
await createEndpoints(app);
19+
20+
if (
21+
certPath &&
22+
keyPath &&
23+
fs.existsSync(certPath) &&
24+
fs.existsSync(keyPath)
25+
) {
26+
const server = https.createServer(
27+
{
28+
key: fs.readFileSync(keyPath),
29+
cert: fs.readFileSync(certPath),
30+
},
31+
app
32+
);
33+
server.listen(HTTPS_SERVER_PORT, HOST, () => {
34+
console.log(`HTTPS server is running on port ${HTTPS_SERVER_PORT}`);
35+
});
36+
return server;
37+
} else {
38+
const server = http.createServer(app);
39+
server.listen(HTTP_SERVER_PORT, HOST, () => {
40+
console.log(`HTTP server is running on port ${HTTP_SERVER_PORT}`);
41+
});
42+
return server;
43+
}
44+
}
45+
46+
async function createEndpoints(app: express.Express) {
47+
app.use(express.json());
48+
49+
app.get("/:instanceId/", (req, res) => {
50+
const instanceId = req.params.instanceId;
51+
if (instanceId !== process.env.INSTANCE_ID) {
52+
return res.status(400).send("Invalid instance ID");
53+
}
54+
// Get the requested URL
55+
const serverUrl = req.protocol + "://" + req.get("host") + req.originalUrl;
56+
57+
// Redirect to https://editor.pulse-editor.com and append
58+
// this instance's URL as a query parameter
59+
const url = new URL(
60+
process.env.FRONTEND_URL ?? "https://editor.pulse-editor.com"
61+
);
62+
url.searchParams.append("instance", serverUrl);
63+
res.redirect(url.toString());
64+
});
65+
66+
app.get("/:instanceId/test", (req, res) => {
67+
const instanceId = req.params.instanceId;
68+
if (instanceId !== process.env.INSTANCE_ID) {
69+
return res.status(400).send("Invalid instance ID");
70+
}
71+
res.send("Remote instance is running!");
72+
});
73+
74+
app.post("/:instanceId/platform-api", async (req, res) => {
75+
const instanceId = req.params.instanceId;
76+
if (instanceId !== process.env.INSTANCE_ID) {
77+
return res.status(400).send("Invalid instance ID");
78+
}
79+
80+
// Get json body
81+
const body = req.body;
82+
83+
console.log("Received platform API request:", body);
84+
85+
const host = req.host;
86+
87+
const result = await handlePlatformAPIRequest(
88+
body,
89+
host,
90+
instanceId
91+
);
92+
93+
// Process the request and send a response
94+
res.send(result);
95+
});
96+
}

0 commit comments

Comments
 (0)