Spaces:
Sleeping
Sleeping
Upload 9 files
Browse files- .dockerignore +1 -0
- .eslintrc.js +0 -0
- Dockerfile +20 -0
- package.json +39 -0
- src/index.ts +43 -0
- src/server.ts +23 -0
- tsconfig.json +33 -0
- tsup.config.ts +8 -0
- turbo.json +8 -0
.dockerignore
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
node_modules
|
.eslintrc.js
ADDED
File without changes
|
Dockerfile
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
FROM node:21.7.3
|
2 |
+
|
3 |
+
RUN useradd -ms /bin/bash api
|
4 |
+
# /home/api \
|
5 |
+
|
6 |
+
WORKDIR /home/api
|
7 |
+
|
8 |
+
COPY package*.json /home/api/
|
9 |
+
|
10 |
+
RUN corepack enable pnpm
|
11 |
+
|
12 |
+
RUN pnpm install
|
13 |
+
|
14 |
+
COPY . .
|
15 |
+
|
16 |
+
USER api
|
17 |
+
|
18 |
+
EXPOSE 5001
|
19 |
+
|
20 |
+
CMD ["pnpm", "start"]
|
package.json
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "api",
|
3 |
+
"version": "0.0.0",
|
4 |
+
"private": true,
|
5 |
+
"scripts": {
|
6 |
+
"start": "node dist/index.js",
|
7 |
+
"dev": "tsup --watch --onSuccess \"node dist/index.js\"",
|
8 |
+
"build": "tsup",
|
9 |
+
"clean": "rm -rf dist",
|
10 |
+
"typecheck": "tsc --noEmit",
|
11 |
+
"lint": "eslint src/",
|
12 |
+
"test": "jest --detectOpenHandles"
|
13 |
+
},
|
14 |
+
"jest": {
|
15 |
+
"preset": "@repo/jest-presets/node"
|
16 |
+
},
|
17 |
+
"dependencies": {
|
18 |
+
"body-parser": "^1.20.2",
|
19 |
+
"cors": "^2.8.5",
|
20 |
+
"express": "^4.18.3",
|
21 |
+
"morgan": "^1.10.0",
|
22 |
+
"node-pty": "^1.0.0",
|
23 |
+
"ws": "^8.16.0"
|
24 |
+
},
|
25 |
+
"devDependencies": {
|
26 |
+
"@types/body-parser": "^1.19.5",
|
27 |
+
"@types/cors": "^2.8.17",
|
28 |
+
"@types/express": "^4.17.21",
|
29 |
+
"@types/jest": "^29.5.12",
|
30 |
+
"@types/morgan": "^1.9.9",
|
31 |
+
"@types/node": "^20.11.24",
|
32 |
+
"@types/supertest": "^6.0.2",
|
33 |
+
"@types/ws": "^8.5.10",
|
34 |
+
"jest": "^29.7.0",
|
35 |
+
"supertest": "^6.3.4",
|
36 |
+
"tsup": "^8.0.2",
|
37 |
+
"typescript": "^5.3.3"
|
38 |
+
}
|
39 |
+
}
|
src/index.ts
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import http from "node:http";
|
2 |
+
import { WebSocketServer } from "ws";
|
3 |
+
import { spawn } from "node-pty";
|
4 |
+
import { createServer } from "./server";
|
5 |
+
|
6 |
+
const port = process.env.PORT || 5001;
|
7 |
+
const app = createServer();
|
8 |
+
const server = http.createServer(app);
|
9 |
+
const wss = new WebSocketServer({ server });
|
10 |
+
|
11 |
+
wss.on("connection", (ws) => {
|
12 |
+
const ptyProcess = spawn("bash", [], {
|
13 |
+
name: "xterm-color",
|
14 |
+
env: process.env,
|
15 |
+
});
|
16 |
+
|
17 |
+
ws.on("message", (message) => {
|
18 |
+
console.log(`received: ${message}`);
|
19 |
+
|
20 |
+
const data = JSON.parse(message.toString());
|
21 |
+
|
22 |
+
if (data.type === "command") {
|
23 |
+
ptyProcess.write(data.data);
|
24 |
+
}
|
25 |
+
});
|
26 |
+
|
27 |
+
ws.on("close", () => {
|
28 |
+
console.log("closed ws");
|
29 |
+
});
|
30 |
+
|
31 |
+
ptyProcess.onData((data) => {
|
32 |
+
const message = JSON.stringify({
|
33 |
+
type: "data",
|
34 |
+
data,
|
35 |
+
});
|
36 |
+
|
37 |
+
ws.send(message);
|
38 |
+
});
|
39 |
+
});
|
40 |
+
|
41 |
+
server.listen(port, () => {
|
42 |
+
console.log(`api running on ${port}`);
|
43 |
+
});
|
src/server.ts
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { json, urlencoded } from "body-parser";
|
2 |
+
import express, { type Express } from "express";
|
3 |
+
import morgan from "morgan";
|
4 |
+
import cors from "cors";
|
5 |
+
|
6 |
+
export const createServer = (): Express => {
|
7 |
+
const app = express();
|
8 |
+
|
9 |
+
app
|
10 |
+
.disable("x-powered-by")
|
11 |
+
.use(morgan("dev"))
|
12 |
+
.use(urlencoded({ extended: true }))
|
13 |
+
.use(json())
|
14 |
+
.use(cors())
|
15 |
+
.get("/message/:name", (req, res) => {
|
16 |
+
return res.json({ message: `hello ${req.params.name}` });
|
17 |
+
})
|
18 |
+
.get("/status", (_, res) => {
|
19 |
+
return res.json({ ok: true });
|
20 |
+
});
|
21 |
+
|
22 |
+
return app;
|
23 |
+
};
|
tsconfig.json
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"$schema": "https://json.schemastore.org/tsconfig",
|
3 |
+
"display": "Default",
|
4 |
+
"compilerOptions": {
|
5 |
+
"composite": false,
|
6 |
+
"declaration": true,
|
7 |
+
"declarationMap": true,
|
8 |
+
"esModuleInterop": true,
|
9 |
+
"forceConsistentCasingInFileNames": true,
|
10 |
+
"allowImportingTsExtensions": true,
|
11 |
+
"inlineSources": false,
|
12 |
+
"isolatedModules": true,
|
13 |
+
"module": "ESNext",
|
14 |
+
"moduleResolution": "Bundler",
|
15 |
+
"noUnusedLocals": false,
|
16 |
+
"noUnusedParameters": false,
|
17 |
+
"preserveWatchOutput": true,
|
18 |
+
"skipLibCheck": true,
|
19 |
+
"strict": true,
|
20 |
+
"noEmit": true,
|
21 |
+
"strictNullChecks": true,
|
22 |
+
"lib": [
|
23 |
+
"ES2015"
|
24 |
+
],
|
25 |
+
"outDir": "./dist"
|
26 |
+
},
|
27 |
+
"exclude": [
|
28 |
+
"node_modules"
|
29 |
+
],
|
30 |
+
"include": [
|
31 |
+
"."
|
32 |
+
]
|
33 |
+
}
|
tsup.config.ts
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { defineConfig, type Options } from "tsup";
|
2 |
+
|
3 |
+
export default defineConfig((options: Options) => ({
|
4 |
+
entryPoints: ["src/index.ts"],
|
5 |
+
clean: true,
|
6 |
+
format: ["cjs"],
|
7 |
+
...options,
|
8 |
+
}));
|
turbo.json
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"extends": ["//"],
|
3 |
+
"pipeline": {
|
4 |
+
"build": {
|
5 |
+
"outputs": ["dist/**"]
|
6 |
+
}
|
7 |
+
}
|
8 |
+
}
|