diff --git a/README.md b/README.md new file mode 100644 index 0000000..2c087ad --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# Code Execution +Code Execution plugin for [TypingMind](https://typingmind.com) powered by [Judge0](https://judge0.com). + +## Get Started +1. Get your code execution API key [here](https://judge0.com/ce). +2. Click the *Settings* tab and enter your RapidAPI Key. + +## Supported Languages +C, C++, Go, Python, Java, JavaScript, Ruby. + +## Example Usage +``` +Run the following Python code: +def fibonacci(n): + if n <= 1: + return n + else: + return fibonacci(n-1) + fibonacci(n-2) +print(fibonacci(10)) +``` + +--- + +``` +Run this C++ code: +#include + +int main() { + std::cout << "Hello from TypingMind!\n"; + return 0; +} +``` + +## Contribute +Your contributions are welcome via [GitHub](https://github.com/judge0/typingmind). diff --git a/plugin.js b/plugin.js new file mode 100644 index 0000000..a14e12a --- /dev/null +++ b/plugin.js @@ -0,0 +1,66 @@ +const LANGUAGE_IDS = { // https://ce.judge0.com/languages + "c": 50, + "cpp": 54, + "go": 95, + "java": 91, + "javascript": 93, + "python": 92, + "ruby": 72 +}; + +const LANGUAGE_ALIASES = { + "c++": "cpp", + "golang": "go", + "js": "javascript" +} + +function getLanguageId(language) { + let l = language.toLowerCase(); + return LANGUAGE_IDS[LANGUAGE_ALIASES[l] || l] || 0; +} + +function encode(str) { + return btoa(unescape(encodeURIComponent(str || ""))); +} + +function decode(bytes) { + var escaped = escape(atob(bytes || "")); + try { + return decodeURIComponent(escaped); + } catch { + return unescape(escaped); + } +} + +async function code_execution(params, userSettings) { + const { source_code, language } = params; + const { rapidApiKey } = userSettings; + + const languageId = getLanguageId(language); + if (languageId == 0) { + return `Unsupported language ${language}`; + } + + const requestHeaders = new Headers(); + requestHeaders.append("x-rapidapi-key", rapidApiKey); + requestHeaders.append("Content-Type", "application/json"); + + const requestData = { + "language_id": languageId, + "source_code": encode(source_code), + "redirect_stderr_to_stdout": true + }; + + let response = await fetch("https://judge0-ce.p.rapidapi.com/submissions?base64_encoded=true&wait=true", { + method: "POST", + headers: requestHeaders, + body: JSON.stringify(requestData) + }); + + if (!response.ok) { + return "Network error"; + } + + let responseData = await response.json(); + return [decode(responseData["compile_output"]), decode(responseData["stdout"])].join("\n").trim(); +} diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..6557fd8 --- /dev/null +++ b/settings.json @@ -0,0 +1,7 @@ +[ + { + "name": "rapidApiKey", + "label": "RapidAPI Key", + "type": "password" + } +] diff --git a/spec.json b/spec.json new file mode 100644 index 0000000..b4fd606 --- /dev/null +++ b/spec.json @@ -0,0 +1,21 @@ +{ + "name": "code_execution", + "description": "Run code in various programming languages", + "parameters": { + "type": "object", + "properties": { + "source_code": { + "type": "string", + "description": "A source code snippet" + }, + "language": { + "type": "string", + "description": "A name of the programming language" + } + }, + "required": [ + "source_code", + "language" + ] + } +}