import { pipe } from "fp-ts/lib/function"; import { chain, TaskEither, tryCatch, right, left } from "fp-ts/lib/TaskEither"; import * as qjs from "quickjs-emscripten"; import clone from "lodash/clone"; type EnvEntry = { key: string; value: string; }; export const execPreRequestScript = ( preRequestScript: string, env: EnvEntry[] ): TaskEither => pipe( tryCatch( async () => await qjs.getQuickJS(), (reason) => `QuickJS initialization failed: ${reason}` ), chain( (QuickJS) => { const finalEnv = clone(env) const vm = QuickJS.createVm() const pwHandle = vm.newObject() const envHandle = vm.newObject() const envSetFuncHandle = vm.newFunction("set", (keyHandle, valueHandle) => { const key = vm.dump(keyHandle) const value = vm.dump(valueHandle) if (typeof key !== "string") return { error: vm.newString("Expected key to be a string") } if (typeof value !== "string") return { error: vm.newString("Expected value to be a string") } const keyIndex = finalEnv.findIndex((env) => env.key === key) if (keyIndex === -1) { finalEnv.push({ key, value }) } else { finalEnv[keyIndex] = { key, value } } return { value: vm.undefined } }) vm.setProp(envHandle, "set", envSetFuncHandle) envSetFuncHandle.dispose() vm.setProp(pwHandle, "env", envHandle) envHandle.dispose() vm.setProp(vm.global, "pw", pwHandle) pwHandle.dispose() const evalRes = vm.evalCode(preRequestScript) if (evalRes.error) { const errorData = vm.dump(evalRes.error) evalRes.error.dispose() return left(`Script evaluation failed: ${errorData}`) } vm.dispose() return right(finalEnv) } ) )