Initial setup
This commit is contained in:
1
.buildpacks
Normal file
1
.buildpacks
Normal file
@@ -0,0 +1 @@
|
||||
https://github.com/dokku/buildpack-deno
|
||||
1
Procfile
Normal file
1
Procfile
Normal file
@@ -0,0 +1 @@
|
||||
web: deno run --allow-net --allow-read deno_server.ts
|
||||
28
deno.jsonc
Normal file
28
deno.jsonc
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["deno.window", "deno.worker"]
|
||||
},
|
||||
"lint": {
|
||||
"files": {
|
||||
"include": ["./*.ts"]
|
||||
},
|
||||
"rules": {
|
||||
"tags": ["recommended"],
|
||||
"exclude": ["no-explicit-any"]
|
||||
}
|
||||
},
|
||||
"fmt": {
|
||||
"files": {
|
||||
"include": ["./*.ts"]
|
||||
},
|
||||
"options": {
|
||||
"useTabs": false,
|
||||
"lineWidth": 80,
|
||||
"indentWidth": 2,
|
||||
"singleQuote": false
|
||||
}
|
||||
},
|
||||
"tasks": {
|
||||
"start": "deno run --allow-net --allow-read --unstable-worker-options deno_server.ts"
|
||||
}
|
||||
}
|
||||
96
deno.lock
generated
Normal file
96
deno.lock
generated
Normal file
@@ -0,0 +1,96 @@
|
||||
{
|
||||
"version": "5",
|
||||
"specifiers": {
|
||||
"jsr:@b-fuze/deno-dom@*": "0.1.52"
|
||||
},
|
||||
"jsr": {
|
||||
"@b-fuze/deno-dom@0.1.52": {
|
||||
"integrity": "ddd89594d2bd795cfa2c4dc5f93a94694a8a75b8c17c6b909e8c86157cc90b65"
|
||||
}
|
||||
},
|
||||
"redirects": {
|
||||
"https://deno.land/x/deno_dom/deno-dom-wasm.ts": "https://deno.land/x/deno_dom@v0.1.53/deno-dom-wasm.ts",
|
||||
"https://esm.sh/lodash": "https://esm.sh/lodash@4.17.21"
|
||||
},
|
||||
"remote": {
|
||||
"https://deno.land/std@0.140.0/async/abortable.ts": "87aa7230be8360c24ad437212311c9e8d4328854baec27b4c7abb26e85515c06",
|
||||
"https://deno.land/std@0.140.0/async/deadline.ts": "48ac998d7564969f3e6ec6b6f9bf0217ebd00239b1b2292feba61272d5dd58d0",
|
||||
"https://deno.land/std@0.140.0/async/debounce.ts": "564273ef242bcfcda19a439132f940db8694173abffc159ea34f07d18fc42620",
|
||||
"https://deno.land/std@0.140.0/async/deferred.ts": "bc18e28108252c9f67dfca2bbc4587c3cbf3aeb6e155f8c864ca8ecff992b98a",
|
||||
"https://deno.land/std@0.140.0/async/delay.ts": "cbbdf1c87d1aed8edc7bae13592fb3e27e3106e0748f089c263390d4f49e5f6c",
|
||||
"https://deno.land/std@0.140.0/async/mod.ts": "6e42e275b44367361a81842dd1a789c55ab206d7c8a877d7163ab5c460625be6",
|
||||
"https://deno.land/std@0.140.0/async/mux_async_iterator.ts": "f4d1d259b0c694d381770ddaaa4b799a94843eba80c17f4a2ec2949168e52d1e",
|
||||
"https://deno.land/std@0.140.0/async/pool.ts": "97b0dd27c69544e374df857a40902e74e39532f226005543eabacb551e277082",
|
||||
"https://deno.land/std@0.140.0/async/tee.ts": "1341feb1f5b1a96f8628d0f8fc07d8c43d3813423f18a63bf1b4785568d21b1f",
|
||||
"https://deno.land/std@0.140.0/http/server.ts": "3da75405704bebcf212a55966a68a489f7e094ba52b5d38f181fe0ef8461a55d",
|
||||
"https://deno.land/std@0.201.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee",
|
||||
"https://deno.land/std@0.201.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56",
|
||||
"https://deno.land/std@0.201.0/async/delay.ts": "a6142eb44cdd856b645086af2b811b1fcce08ec06bb7d50969e6a872ee9b8659",
|
||||
"https://deno.land/std@0.201.0/http/server.ts": "1b2403b3c544c0624ad23e8ca4e05877e65380d9e0d75d04957432d65c3d5f41",
|
||||
"https://deno.land/std@0.201.0/path/_basename.ts": "057d420c9049821f983f784fd87fa73ac471901fb628920b67972b0f44319343",
|
||||
"https://deno.land/std@0.201.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
|
||||
"https://deno.land/std@0.201.0/path/_dirname.ts": "355e297236b2218600aee7a5301b937204c62e12da9db4b0b044993d9e658395",
|
||||
"https://deno.land/std@0.201.0/path/_extname.ts": "eaaa5aae1acf1f03254d681bd6a8ce42a9cb5b7ff2213a9d4740e8ab31283664",
|
||||
"https://deno.land/std@0.201.0/path/_format.ts": "4a99270d6810f082e614309164fad75d6f1a483b68eed97c830a506cc589f8b4",
|
||||
"https://deno.land/std@0.201.0/path/_from_file_url.ts": "6eadfae2e6f63ad9ee46b26db4a1b16583055c0392acedfb50ed2fc694b6f581",
|
||||
"https://deno.land/std@0.201.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b",
|
||||
"https://deno.land/std@0.201.0/path/_is_absolute.ts": "05dac10b5e93c63198b92e3687baa2be178df5321c527dc555266c0f4f51558c",
|
||||
"https://deno.land/std@0.201.0/path/_join.ts": "815f5e85b042285175b1492dd5781240ce126c23bd97bad6b8211fe7129c538e",
|
||||
"https://deno.land/std@0.201.0/path/_normalize.ts": "a19ec8706b2707f9dd974662a5cd89fad438e62ab1857e08b314a8eb49a34d81",
|
||||
"https://deno.land/std@0.201.0/path/_os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3",
|
||||
"https://deno.land/std@0.201.0/path/_parse.ts": "0f9b0ff43682dd9964eb1c4398610c4e165d8db9d3ac9d594220217adf480cfa",
|
||||
"https://deno.land/std@0.201.0/path/_relative.ts": "27bdeffb5311a47d85be26d37ad1969979359f7636c5cd9fcf05dcd0d5099dc5",
|
||||
"https://deno.land/std@0.201.0/path/_resolve.ts": "7a3616f1093735ed327e758313b79c3c04ea921808ca5f19ddf240cb68d0adf6",
|
||||
"https://deno.land/std@0.201.0/path/_to_file_url.ts": "a141e4a525303e1a3a0c0571fd024552b5f3553a2af7d75d1ff3a503dcbb66d8",
|
||||
"https://deno.land/std@0.201.0/path/_to_namespaced_path.ts": "0d5f4caa2ed98ef7a8786286df6af804b50e38859ae897b5b5b4c8c5930a75c8",
|
||||
"https://deno.land/std@0.201.0/path/_util.ts": "4e191b1bac6b3bf0c31aab42e5ca2e01a86ab5a0d2e08b75acf8585047a86221",
|
||||
"https://deno.land/std@0.201.0/path/basename.ts": "bdfa5a624c6a45564dc6758ef2077f2822978a6dbe77b0a3514f7d1f81362930",
|
||||
"https://deno.land/std@0.201.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000",
|
||||
"https://deno.land/std@0.201.0/path/dirname.ts": "b6533f4ee4174a526dec50c279534df5345836dfdc15318400b08c62a62a39dd",
|
||||
"https://deno.land/std@0.201.0/path/extname.ts": "62c4b376300795342fe1e4746c0de518b4dc9c4b0b4617bfee62a2973a9555cf",
|
||||
"https://deno.land/std@0.201.0/path/format.ts": "110270b238514dd68455a4c54956215a1aff7e37e22e4427b7771cefe1920aa5",
|
||||
"https://deno.land/std@0.201.0/path/from_file_url.ts": "9f5cb58d58be14c775ec2e57fc70029ac8b17ed3bd7fe93e475b07280adde0ac",
|
||||
"https://deno.land/std@0.201.0/path/glob.ts": "593e2c3573883225c25c5a21aaa8e9382a696b8e175ea20a3b6a1471ad17aaed",
|
||||
"https://deno.land/std@0.201.0/path/is_absolute.ts": "0b92eb35a0a8780e9f16f16bb23655b67dace6a8e0d92d42039e518ee38103c1",
|
||||
"https://deno.land/std@0.201.0/path/join.ts": "31c5419f23d91655b08ec7aec403f4e4cd1a63d39e28f6e42642ea207c2734f8",
|
||||
"https://deno.land/std@0.201.0/path/mod.ts": "6e1efb0b13121463aedb53ea51dabf5639a3172ab58c89900bbb72b486872532",
|
||||
"https://deno.land/std@0.201.0/path/normalize.ts": "6ea523e0040979dd7ae2f1be5bf2083941881a252554c0f32566a18b03021955",
|
||||
"https://deno.land/std@0.201.0/path/parse.ts": "be8de342bb9e1924d78dc4d93c45215c152db7bf738ec32475560424b119b394",
|
||||
"https://deno.land/std@0.201.0/path/posix.ts": "0a1c1952d132323a88736d03e92bd236f3ed5f9f079e5823fae07c8d978ee61b",
|
||||
"https://deno.land/std@0.201.0/path/relative.ts": "8bedac226afd360afc45d451a6c29fabceaf32978526bcb38e0c852661f66c61",
|
||||
"https://deno.land/std@0.201.0/path/resolve.ts": "133161e4949fc97f9ca67988d51376b0f5eef8968a6372325ab84d39d30b80dc",
|
||||
"https://deno.land/std@0.201.0/path/separator.ts": "40a3e9a4ad10bef23bc2cd6c610291b6c502a06237c2c4cd034a15ca78dedc1f",
|
||||
"https://deno.land/std@0.201.0/path/to_file_url.ts": "00e6322373dd51ad109956b775e4e72e5f9fa68ce2c6b04e4af2a6eed3825d31",
|
||||
"https://deno.land/std@0.201.0/path/to_namespaced_path.ts": "1b1db3055c343ab389901adfbda34e82b7386bcd1c744d54f9c1496ee0fd0c3d",
|
||||
"https://deno.land/std@0.201.0/path/win32.ts": "8b3f80ef7a462511d5e8020ff490edcaa0a0d118f1b1e9da50e2916bdd73f9dd",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/build/deno-wasm/deno-wasm.js": "567c1baaf7d3c381cb9c35937403cbaa83bdaa2ae2f4bf59230648c4e3349a0d",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/build/deno-wasm/deno-wasm_bg-wasm.js": "989a0f81b2270eb172bcaf48de4a98da2a3a3bbcf5df334e64602bc8712aec2e",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/build/deno-wasm/deno-wasm_bg.wasm": "05645f46bbdd0fb2a0f5ff759885f553919af1586c3a93fdd29393a6c2920728",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/build/deno-wasm/env.js": "17da784c11b192c591dbf7df21ec6f65f63f45ca9a713e4ca100f3c886b4023f",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/build/deno-wasm/wbg.js": "b5b6de12bc010fa23438c8a8276067b9044a405da516d0bbe4ae61b7c6d61a22",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/deno-dom-wasm.ts": "4f8ede24992eb4b3426c3930a511d9f33e4db8fe81ca8d1c63ed12f0a76ac3a4",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/api.ts": "0ff5790f0a3eeecb4e00b7d8fbfa319b165962cf6d0182a65ba90f158d74f7d7",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/constructor-lock.ts": "0e7b297e8b9cf921a3b0d3a692ec5fb462c5afc47ec554292e20090b9e16b40a",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/deserialize.ts": "514953418b7ae558ed7361ad9be21013f46cba2f58bd7f4acc90cf1e89f9c8cf",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/document-fragment.ts": "0b915d094830d43b330dc2fb8012b990f2c815773c6cdcd4a9fdff99fe47412e",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/document.ts": "ad584ac4ce6dce03f0ff6ef4b7db86fd598f9c7824da1387f7f2acd7d6948e4a",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/dom-parser.ts": "784ee0e766d4a01e14420f328053fd3a0016c6b40ee442edc3ae80f5d9777927",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/element.ts": "7d330192fbfd406fb67ab7a3387576fe35fec129b7c52c2ea38615144fa5b12e",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/elements/html-template-element.ts": "1707dfb4cbb145f3bcb94426d7cdedbaa336620d0afed30e99f50fe87ba24a98",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/html-collection.ts": "dcf328e883877f7748d3e20fb6319e739f297a6e24f4b00ec5b1a2f390cfa3c6",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/node-list.ts": "be9793475d82539da8b97a17b6b5538cc723538c10cc5820a23e5e4b2248845d",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/node.ts": "53ada9e4b2ae21f10f5941ff257ed4585920ae392020544648f349c05d15d30c",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/selectors/custom-api.ts": "852696bd58e534bc41bd3be9e2250b60b67cd95fd28ed16b1deff1d548531a71",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/selectors/nwsapi-types.ts": "c43b36c36acc5d32caabaa54fda8c9d239b2b0fcbce9a28efb93c84aa1021698",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/selectors/nwsapi.js": "985d7d8fc1eabbb88946b47a1c44c1b2d4aa79ff23c21424219f1528fa27a2ff",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/selectors/selectors.ts": "83eab57be2290fb48e3130533448c93c6c61239f2a2f3b85f1917f80ca0fdc75",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/selectors/sizzle-types.ts": "78149e2502409989ce861ed636b813b059e16bc267bb543e7c2b26ef43e4798b",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/selectors/sizzle.js": "c3aed60c1045a106d8e546ac2f85cc82e65f62d9af2f8f515210b9212286682a",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/string-cache.ts": "8e935804f7bac244cc70cec90a28c9f6d30fea14c61c2c4ea48fca274376d786",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/utils-types.ts": "96db30e3e4a75b194201bb9fa30988215da7f91b380fca6a5143e51ece2a8436",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/dom/utils.ts": "bc429635e9204051ba1ecc1b212031b5ee7c6bcd95120c91bef696804aa67e74",
|
||||
"https://deno.land/x/deno_dom@v0.1.53/src/parser.ts": "e06b2300d693e6ae7564e53dfa5c9a9e97fdb8c044c39c52c8b93b5d60860be3",
|
||||
"https://esm.sh/lodash@4.17.21": "c2f90ffd948b7a30f054986888bdc2667824115fa48ad583ca8b3a579ca4a5a8",
|
||||
"https://esm.sh/lodash@4.17.21/denonext/lodash.mjs": "9d2a44e584d91008f61f974c6d0a32bf9afb1563761e60c366af0a293e8c759b"
|
||||
}
|
||||
}
|
||||
73
deno_server.ts
Normal file
73
deno_server.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
// isolator/deno_server.ts
|
||||
import { serve } from "https://deno.land/std@0.201.0/http/server.ts";
|
||||
|
||||
const TIMEOUT_MS = 5_000;
|
||||
const States = Object.freeze({
|
||||
TIMEOUT: "TIMEOUT",
|
||||
});
|
||||
|
||||
async function handler(req: Request): Promise<Response> {
|
||||
if (req.method !== "POST" || new URL(req.url).pathname !== "/execute") {
|
||||
return new Response("Not Found", { status: 404 });
|
||||
}
|
||||
|
||||
try {
|
||||
const body = await req.json();
|
||||
const { code = "", request = {}, environment = {}, name } = body;
|
||||
|
||||
const worker = new Worker(new URL("./worker.ts", import.meta.url).href, {
|
||||
type: "module",
|
||||
// The `deno` option is now stable, but your editor might show a TS error
|
||||
// if it's not configured for Deno. This will run correctly with Deno.
|
||||
deno: {
|
||||
namespace: true, // recommended for workers
|
||||
permissions: "inherit",
|
||||
},
|
||||
});
|
||||
|
||||
const executionPromise = new Promise((resolve, reject) => {
|
||||
worker.onmessage = (e) => {
|
||||
resolve(e.data);
|
||||
worker.terminate();
|
||||
};
|
||||
worker.onerror = (e) => {
|
||||
reject(new Error(`Worker error: ${e.message}`));
|
||||
worker.terminate();
|
||||
};
|
||||
});
|
||||
|
||||
const timeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error("Timeout")), TIMEOUT_MS)
|
||||
);
|
||||
|
||||
worker.postMessage({ code, request, environment, name });
|
||||
|
||||
const startTime = performance.now();
|
||||
try {
|
||||
const result = await Promise.race([executionPromise, timeoutPromise]);
|
||||
return new Response(JSON.stringify(result), {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
} catch (err) {
|
||||
worker.terminate();
|
||||
const executionTime = performance.now() - startTime;
|
||||
const payload = {
|
||||
status: States.TIMEOUT,
|
||||
result: err.message,
|
||||
logs: [],
|
||||
environment: environment,
|
||||
execution_time: executionTime,
|
||||
};
|
||||
return new Response(JSON.stringify(payload), {
|
||||
status: 500,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
return new Response(`Bad Request: ${e.message}`, { status: 400 });
|
||||
}
|
||||
}
|
||||
|
||||
console.log("⚡ Deno server ready on :8000");
|
||||
|
||||
await serve(handler, { port: 8000 });
|
||||
93
worker.ts
Normal file
93
worker.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
// isolator/worker.ts
|
||||
const States = Object.freeze({
|
||||
SUCCESS: "SUCCESS",
|
||||
NOT_A_FUNCTION: "NOT_A_FUNCTION",
|
||||
SCRIPT_ERROR: "ERROR",
|
||||
});
|
||||
|
||||
self.onmessage = async (e) => {
|
||||
const { code, request, environment } = e.data;
|
||||
const logs: any[] = [];
|
||||
const startTime = performance.now();
|
||||
|
||||
// Temporarily override console.log and console.error to capture logs
|
||||
const oldConsoleLog = console.log;
|
||||
const oldConsoleError = console.error;
|
||||
console.log = (...args) => {
|
||||
logs.push(args);
|
||||
oldConsoleLog.apply(console, args);
|
||||
};
|
||||
console.error = (...args) => {
|
||||
logs.push(args);
|
||||
oldConsoleError.apply(console, args);
|
||||
};
|
||||
|
||||
try {
|
||||
// Make the environment object and response helpers available globally.
|
||||
(self as any).environment = environment;
|
||||
(self as any).Response = (body = "", headers = {}, status = 200) => ({
|
||||
body,
|
||||
status,
|
||||
headers,
|
||||
});
|
||||
(self as any).JsonResponse = (body = {}, headers = {}, status = 200) =>
|
||||
(self as any).Response(
|
||||
JSON.stringify(body),
|
||||
{ "Content-Type": "application/json", ...headers },
|
||||
status
|
||||
);
|
||||
(self as any).HtmlResponse = (body = "", headers = {}, status = 200) =>
|
||||
(self as any).Response(
|
||||
body,
|
||||
{ "Content-Type": "text/html", ...headers },
|
||||
status
|
||||
);
|
||||
(self as any).TextResponse = (body = "", headers = {}, status = 200) =>
|
||||
(self as any).Response(
|
||||
body,
|
||||
{ "Content-Type": "text/plain", ...headers },
|
||||
status
|
||||
);
|
||||
|
||||
// Use a data URL to import the user's code as an ES module.
|
||||
const dataUrl = `data:text/javascript;base64,${btoa(
|
||||
unescape(encodeURIComponent(code))
|
||||
)}`;
|
||||
const userModule = await import(dataUrl);
|
||||
|
||||
if (typeof userModule.default !== "function") {
|
||||
throw new Error(
|
||||
"Module does not have a default export or the export is not a function."
|
||||
);
|
||||
}
|
||||
|
||||
const userFn = userModule.default;
|
||||
const result = await userFn(request);
|
||||
const executionTime = performance.now() - startTime;
|
||||
|
||||
self.postMessage({
|
||||
status: States.SUCCESS,
|
||||
result,
|
||||
logs,
|
||||
environment: (self as any).environment, // Return the mutated environment.
|
||||
execution_time: executionTime,
|
||||
});
|
||||
} catch (err) {
|
||||
const executionTime = performance.now() - startTime;
|
||||
self.postMessage({
|
||||
status: States.SCRIPT_ERROR,
|
||||
result: {
|
||||
name: err.name,
|
||||
message: err.message,
|
||||
stack: err.stack,
|
||||
},
|
||||
logs,
|
||||
environment,
|
||||
execution_time: executionTime,
|
||||
});
|
||||
} finally {
|
||||
// Restore original console functions
|
||||
console.log = oldConsoleLog;
|
||||
console.error = oldConsoleError;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user