refactor(scripting-revamp): migrate js-sandbox to web worker/Node vm based implementation (#3619)

This commit is contained in:
James George
2023-12-07 16:10:42 +05:30
committed by GitHub
parent 0a61ec2bfe
commit bdfa14fa54
43 changed files with 2805 additions and 3285 deletions

View File

@@ -0,0 +1,36 @@
import { pipe } from "fp-ts/function"
import * as TE from "fp-ts/lib/TaskEither"
import { createContext, runInContext } from "vm"
import { TestResult } from "~/types"
import { getPreRequestScriptMethods } from "~/utils"
export const runPreRequestScript = (
preRequestScript: string,
envs: TestResult["envs"]
): TE.TaskEither<string, TestResult["envs"]> =>
pipe(
TE.tryCatch(
async () => {
return createContext()
},
(reason) => `Context initialization failed: ${reason}`
),
TE.chain((context) =>
TE.tryCatch(
() =>
new Promise((resolve) => {
const { pw, updatedEnvs } = getPreRequestScriptMethods(envs)
// Expose pw to the context
context.pw = pw
// Run the pre-request script in the provided context
runInContext(preRequestScript, context)
resolve(updatedEnvs)
}),
(reason) => `Script execution failed: ${reason}`
)
)
)

View File

@@ -0,0 +1,24 @@
import * as E from "fp-ts/Either"
import { TestResult } from "~/types"
import Worker from "./worker?worker&inline"
export const runPreRequestScript = (
preRequestScript: string,
envs: TestResult["envs"]
): Promise<E.Either<string, TestResult["envs"]>> =>
new Promise((resolve) => {
const worker = new Worker()
// Listen for the results from the web worker
worker.addEventListener("message", (event: MessageEvent) =>
resolve(event.data.results)
)
// Send the script to the web worker
worker.postMessage({
preRequestScript,
envs,
})
})

View File

@@ -0,0 +1,33 @@
import * as TE from "fp-ts/TaskEither"
import { TestResult } from "~/types"
import { getPreRequestScriptMethods } from "~/utils"
const executeScriptInContext = (
preRequestScript: string,
envs: TestResult["envs"]
): TE.TaskEither<string, TestResult["envs"]> => {
try {
const { pw, updatedEnvs } = getPreRequestScriptMethods(envs)
// Create a function from the pre request script using the `Function` constructor
const executeScript = new Function("pw", preRequestScript)
// Execute the script
executeScript(pw)
return TE.right(updatedEnvs)
} catch (error) {
return TE.left(`Script execution failed: ${(error as Error).message}`)
}
}
// Listen for messages from the main thread
self.addEventListener("message", async (event) => {
const { preRequestScript, envs } = event.data
const results = await executeScriptInContext(preRequestScript, envs)()
// Post the result back to the main thread
self.postMessage({ results })
})