UNPKG

@ones-op/node-host

Version:
78 lines (77 loc) 3.06 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PluginVM = void 0; const node_fs_1 = __importDefault(require("node:fs")); const node_vm_1 = __importDefault(require("node:vm")); class MethodNotFoundError extends Error { } // 部分插件因为错误安装了与内置模块同名的社区模块 // 又因为 vm2 做了兼容处理 导致插件可以正常启动 // 实际上与内置模块同名的社区模块没有参与实际业务代码 // vm 的 require 调整了优先策略 // 先查询第三方的社区模块 如存在会返回第三方的社区模块 // 该策略也可以提前暴露非法安装模块的问题 // 目前先保留一个白名单列表 // 如果是内置模块的白名单 则不查询第三方的社区模块 const NODE_PACKAGE_WHITE_LIST = ['https']; class PluginVM { run(pluginInfo) { const { code, packagePath = '', env } = pluginInfo; const proxy = { global: {}, exports: {}, require: (packageName) => { if (NODE_PACKAGE_WHITE_LIST.includes(packageName)) { // 白名单模块为 node 内置模块 } else { // 拼接相对路径为绝对路径 const path = `${packagePath}/${packageName}`; // 检查一下该模块是否存在 if (node_fs_1.default.existsSync(path)) { // 若存在则认为是 node_modules 模块 // 尝试引用 // 原则上插件打包后的代码不存在 require 引用 // 当前仅为防御性代码 return require(path); } } // 默认为 node 内置模块 return require(packageName); }, console, process, TextEncoder, TextDecoder, Buffer, onesEnv: env, setTimeout, setInterval, setImmediate, clearTimeout, clearInterval, clearImmediate, version: parseInt(process.versions.node.split('.')[0]), }; proxy.global = proxy; const context = node_vm_1.default.createContext(proxy); const script = new node_vm_1.default.Script(code, 'index.js'); script.runInContext(context); this.context = context.exports; } async runMethod(method, ...args) { if (!this.context) throw new Error('VM not initialized'); if (!this.context[method]) { throw new MethodNotFoundError('Method not found' + method); } return await this.context[method](...args); } isMethodNotFoundError(err) { return err instanceof MethodNotFoundError; } } exports.PluginVM = PluginVM;