Replace ivm.module for script
This commit is contained in:
parent
7e43fff018
commit
53d4fc2fa0
File diff suppressed because one or more lines are too long
|
@ -2,9 +2,8 @@ const {
|
||||||
getJsHelperList,
|
getJsHelperList,
|
||||||
} = require("../../../../string-templates/src/helpers/list.js")
|
} = require("../../../../string-templates/src/helpers/list.js")
|
||||||
|
|
||||||
const helpers = getJsHelperList()
|
export const helpers = {
|
||||||
export default {
|
...getJsHelperList(),
|
||||||
...helpers,
|
|
||||||
// pointing stripProtocol to a unexisting function to be able to declare it on isolated-vm
|
// pointing stripProtocol to a unexisting function to be able to declare it on isolated-vm
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line no-undef
|
||||||
|
|
|
@ -16,31 +16,14 @@ class ExecutionTimeoutError extends Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
class ModuleHandler {
|
class ModuleHandler {
|
||||||
private modules: {
|
private modules: string[] = []
|
||||||
import: string
|
|
||||||
moduleKey: string
|
|
||||||
module: ivm.Module
|
|
||||||
}[] = []
|
|
||||||
|
|
||||||
private generateRandomKey = () => `i${crypto.randomUUID().replace(/-/g, "")}`
|
registerModule(code: string) {
|
||||||
|
this.modules.push(code)
|
||||||
registerModule(module: ivm.Module, imports: string) {
|
|
||||||
this.modules.push({
|
|
||||||
moduleKey: this.generateRandomKey(),
|
|
||||||
import: imports,
|
|
||||||
module: module,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
generateImports() {
|
generateImports() {
|
||||||
return this.modules
|
return this.modules.join(";")
|
||||||
.map(m => `import ${m.import} from "${m.moduleKey}"`)
|
|
||||||
.join(";")
|
|
||||||
}
|
|
||||||
|
|
||||||
getModule(key: string) {
|
|
||||||
const module = this.modules.find(m => m.moduleKey === key)
|
|
||||||
return module?.module
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,34 +81,39 @@ export class IsolatedVM implements VM {
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const cryptoModule = this.registerCallbacks({
|
||||||
|
randomUUID: crypto.randomUUID,
|
||||||
|
})
|
||||||
|
|
||||||
const injectedRequire = `const require=function req(val) {
|
const injectedRequire = `const require=function req(val) {
|
||||||
switch (val) {
|
switch (val) {
|
||||||
case "url": return ${urlModule};
|
case "url": return ${urlModule};
|
||||||
case "querystring": return ${querystringModule};
|
case "querystring": return ${querystringModule};
|
||||||
|
case "crypto": return ${cryptoModule};
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
const helpersSource = loadBundle(BundleType.HELPERS)
|
const helpersSource = loadBundle(BundleType.HELPERS)
|
||||||
const helpersModule = this.isolate.compileModuleSync(
|
// const helpersModule = this.isolate.compileModuleSync(
|
||||||
`${injectedRequire};${helpersSource}`
|
// `${injectedRequire};${helpersSource}`
|
||||||
)
|
// )
|
||||||
|
|
||||||
helpersModule.instantiateSync(this.vm, specifier => {
|
// helpersModule.instantiateSync(this.vm, specifier => {
|
||||||
if (specifier === "crypto") {
|
// if (specifier === "crypto") {
|
||||||
const cryptoModule = this.registerCallbacks({
|
// const cryptoModule = this.registerCallbacks({
|
||||||
randomUUID: crypto.randomUUID,
|
// randomUUID: crypto.randomUUID,
|
||||||
})
|
// })
|
||||||
const module = this.isolate.compileModuleSync(
|
// const module = this.isolate.compileModuleSync(
|
||||||
`export default ${cryptoModule}`
|
// `export default ${cryptoModule}`
|
||||||
)
|
// )
|
||||||
module.instantiateSync(this.vm, specifier => {
|
// module.instantiateSync(this.vm, specifier => {
|
||||||
throw new Error(`No imports allowed. Required: ${specifier}`)
|
// throw new Error(`No imports allowed. Required: ${specifier}`)
|
||||||
})
|
// })
|
||||||
return module
|
// return module
|
||||||
}
|
// }
|
||||||
throw new Error(`No imports allowed. Required: ${specifier}`)
|
// throw new Error(`No imports allowed. Required: ${specifier}`)
|
||||||
})
|
// })
|
||||||
|
|
||||||
this.moduleHandler.registerModule(helpersModule, "helpers")
|
this.moduleHandler.registerModule(`${injectedRequire};${helpersSource}`)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +179,11 @@ export class IsolatedVM implements VM {
|
||||||
throw new Error(`No imports allowed. Required: ${specifier}`)
|
throw new Error(`No imports allowed. Required: ${specifier}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
this.moduleHandler.registerModule(bsonModule, "{deserialize, toJson}")
|
this.moduleHandler.registerModule(
|
||||||
|
bsonModule,
|
||||||
|
"{deserialize, toJson}",
|
||||||
|
"bson"
|
||||||
|
)
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -206,25 +198,13 @@ export class IsolatedVM implements VM {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
code = `${this.moduleHandler.generateImports()};results.out=${this.codeWrapper(
|
code = `${this.moduleHandler.generateImports()};${this.codeWrapper(code)};`
|
||||||
code
|
|
||||||
)};`
|
|
||||||
|
|
||||||
const script = this.isolate.compileModuleSync(code)
|
const script = this.isolate.compileScriptSync(code)
|
||||||
|
|
||||||
script.instantiateSync(this.vm, specifier => {
|
const result = script.runSync(this.vm, { timeout: this.invocationTimeout })
|
||||||
const module = this.moduleHandler.getModule(specifier)
|
|
||||||
if (module) {
|
|
||||||
return module
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`"${specifier}" import not allowed`)
|
return result
|
||||||
})
|
|
||||||
|
|
||||||
script.evaluateSync({ timeout: this.invocationTimeout })
|
|
||||||
|
|
||||||
const result = this.getFromContext(this.resultKey)
|
|
||||||
return result.out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerCallbacks(functions: Record<string, any>) {
|
private registerCallbacks(functions: Record<string, any>) {
|
||||||
|
@ -260,11 +240,4 @@ export class IsolatedVM implements VM {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getFromContext(key: string) {
|
|
||||||
const ref = this.vm.global.getSync(key, { reference: true })
|
|
||||||
const result = ref.copySync()
|
|
||||||
ref.release()
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue