Skip to content

Commit 3a8a73c

Browse files
[v0.0.2 🎉] change ui improve code 🐱‍🏍🚀
1 parent 4d5dea1 commit 3a8a73c

21 files changed

Lines changed: 682 additions & 330 deletions

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ RUN npm install
1919
COPY . .
2020

2121
# Set environment variables
22-
ENV PORT=6000
22+
ENV PORT=9091
2323

2424
# Create a temporary directory that will be used for mounting (if it doesn't exist on host)
2525
# This command ensures the directory exists within the image,
@@ -28,7 +28,7 @@ ENV PORT=6000
2828
RUN mkdir -p /app/temp
2929

3030
# Expose the port your Node.js application listens on
31-
EXPOSE 6000
31+
EXPOSE 9091
3232

3333
# Command to run your application when the container starts
3434
CMD ["npm", "start"]

app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ app.use((req, res) => {
113113
res.type("txt").send("404 not found");
114114
}
115115
});
116-
const PORT = process.env.PORT || 6000;
116+
const PORT = process.env.PORT || 9091;
117117
app.listen(PORT, () => {
118118
console.log(`Code executor backend listening on port ${PORT}`);
119119
});

changelog.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
## v0.0.1 Releases 🎉
2+
3+
- **Multi-Language Support:** Out-of-the-box support for Python, Node.js, and Java code execution.
4+
- **Secure Docker Isolation:** Each code execution runs within its own ephemeral Docker container, ensuring process isolation and security.
5+
- **Resource Limiting:** Configurable memory and CPU limits are applied to each execution to prevent abuse and manage system resources efficiently.
6+
- **API-Driven:** A simple, intuitive RESTful API endpoint (`POST /run`) for easy integration with your applications.
7+
- **Automated Cleanup:** Temporary execution directories and files are automatically managed and removed after execution.
8+
- **Containerized Deployment:** Easily deployable using Docker and Docker Compose, simplifying setup and dependency management.
9+
10+
## v0.0.2 Releases 🎉
11+
12+
- **TypeScript** Language support with `denoland`
13+
- Extracted actual error from the whole error
14+
- Readable and user-friendly output details error
15+
- Reduce execution time
16+
- Root routes and invalid path view `html` page setup
17+
- Improve websites code complex issue
18+
- Use server action to hide **API endpoint**

docker-compose.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ services:
3232
- PORT=${PORT}
3333
- HOST_PROJECT_ROOT=${PWD}
3434
ports:
35-
- "6000:6000"
35+
- "9091:9091"
3636
volumes:
3737
- /var/run/docker.sock:/var/run/docker.sock
3838
- ./temp:/app/temp

websites/.env.example

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
SERVER_BASE_URL="http://localhost:6000"
1+
SERVER_BASE_URL=""
2+
SERVER_BASE_URL_LOCAL="http://localhost:9091"

websites/.env.local

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SERVER_BASE_URL_LOCAL="http://localhost:9091"

websites/src/@types/index.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,19 @@ import { LANGUAGE_MAP } from "@/constants";
22

33
export type Language = keyof typeof LANGUAGE_MAP;
44
export type Status = "success" | "error" | "running";
5+
6+
export type Input = {
7+
language: Language;
8+
code: string;
9+
};
10+
11+
export type Output = {
12+
output: string;
13+
responseTime: number; // in milliseconds
14+
};
15+
516
export type ExecutionResult = {
617
status: Status;
7-
output: string;
8-
executionTime: number;
18+
results: Output;
919
language: Language;
1020
};

websites/src/app/_actions/execute.ts

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
11
"use server";
22

3-
import { Language } from "@/@types";
3+
import { Input, Output } from "@/@types";
44
import { baseUri } from "@/constants/base";
55
import axios from "axios";
66
import { performance } from "perf_hooks";
77

8-
type Input = {
9-
language: Language;
10-
code: string;
11-
};
12-
13-
type Output = {
14-
output: string;
15-
responseTime: number; // in milliseconds
16-
};
17-
188
export async function executeCodeAction(input: Input): Promise<Output> {
199
const start = performance.now();
20-
10+
console.log("baseurl: ", baseUri);
2111
try {
2212
const response = await axios.post(`${baseUri}/run`, input);
2313
const end = performance.now();
@@ -35,14 +25,6 @@ export async function executeCodeAction(input: Input): Promise<Output> {
3525
const errorMessage =
3626
error?.response?.data?.details || "Unknown error occurred";
3727

38-
// Optional: log more useful error info for debugging
39-
console.error("executeCodeAction Error:", {
40-
message: errorMessage,
41-
status: error?.response?.status,
42-
data: error?.response?.data,
43-
});
44-
45-
// Throw a serializable error object
4628
throw new Error(
4729
JSON.stringify({
4830
output: errorMessage,
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
"use client";
2+
import {
3+
Card,
4+
CardContent,
5+
CardDescription,
6+
CardHeader,
7+
CardTitle,
8+
} from "@/components/ui/card";
9+
import { Clock, Code2, Play } from "lucide-react";
10+
import LanguageSelection from "./editor-view/language-selection";
11+
import { Button } from "@/components/ui/button";
12+
import { ExecutionResult, Language, Output } from "@/@types";
13+
import { useState, useTransition } from "react";
14+
import { executeCodeAction } from "../_actions/execute";
15+
import { CodeEditor } from "./editor-view/code-editor";
16+
import ResultSection from "./output-view/result-sections";
17+
18+
export default function CodeInput() {
19+
const [selectedLanguage, setSelectedLanguage] =
20+
useState<Language>("typescript");
21+
const [code, setCode] = useState("");
22+
const [executionResult, setExecutionResult] =
23+
useState<ExecutionResult | null>(null);
24+
const [isExecuting, startExecution] = useTransition();
25+
26+
const executeCode = async () => {
27+
if (!code.trim()) return;
28+
startExecution(async () => {
29+
setExecutionResult({
30+
status: "running",
31+
results: {
32+
output: "",
33+
responseTime: 0,
34+
},
35+
language: selectedLanguage,
36+
});
37+
try {
38+
const data = await executeCodeAction({
39+
language: selectedLanguage,
40+
code,
41+
});
42+
setExecutionResult({
43+
status: "success",
44+
results: {
45+
output: data.output,
46+
responseTime: data.responseTime,
47+
},
48+
language: selectedLanguage,
49+
});
50+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
51+
} catch (err: any) {
52+
const error = JSON.parse(err.message) as Output;
53+
setExecutionResult({
54+
status: "error",
55+
results: {
56+
output: error.output,
57+
responseTime: error.responseTime,
58+
},
59+
language: selectedLanguage,
60+
});
61+
}
62+
});
63+
};
64+
return (
65+
<>
66+
<Card className="h-fit bg-white/5 backdrop-blur-sm border border-white/10 text-white">
67+
<CardHeader className="flex justify-between">
68+
<div>
69+
<CardTitle className="flex items-center gap-2 text-white">
70+
<Code2 className="w-6 h-6 text-purple-400" />
71+
Code Editor
72+
</CardTitle>
73+
<CardDescription className="text-gray-300">
74+
Write or upload your code with full syntax highlighting
75+
</CardDescription>
76+
</div>
77+
{/* Language Selection */}
78+
<LanguageSelection
79+
selectedLanguage={selectedLanguage}
80+
setSelectedLanguage={setSelectedLanguage}
81+
/>
82+
</CardHeader>
83+
<CardContent className="space-y-4">
84+
<CodeEditor
85+
value={code}
86+
onChange={setCode}
87+
language={selectedLanguage}
88+
height="310px"
89+
/>
90+
91+
<Button
92+
onClick={executeCode}
93+
disabled={isExecuting || !code.trim()}
94+
className="w-full bg-gradient-to-r from-purple-600 to-pink-600 text-white hover:from-purple-700 hover:to-pink-700 transition-all duration-300 transform hover:scale-105 shadow-lg"
95+
size="lg"
96+
>
97+
{isExecuting ? (
98+
<>
99+
<Clock className="w-5 h-5 mr-2 animate-spin" />
100+
Executing...
101+
</>
102+
) : (
103+
<>
104+
<Play className="w-5 h-5 mr-2" />
105+
Execute Code
106+
</>
107+
)}
108+
</Button>
109+
</CardContent>
110+
</Card>
111+
<ResultSection optional={executionResult} isExecuting={isExecuting} />
112+
</>
113+
);
114+
}
File renamed without changes.

0 commit comments

Comments
 (0)