|
|
import React from 'react'
type Context = Record<string, any>;
/** * 动态执行 JavaScript 脚本的工具类 */ export class DynamicScriptExecutor { private context: Context private startDelimiter: string private endDelimiter: string
constructor(context: Context = {}, startDelimiter: string = '{{', endDelimiter: string = '}}') { this.context = context this.startDelimiter = startDelimiter this.endDelimiter = endDelimiter }
setDelimiters(startDelimiter: string, endDelimiter: string) { this.startDelimiter = startDelimiter this.endDelimiter = endDelimiter }
setContext(context: Context) { this.context = { ...this.context, ...context } }
// 检测JS代码的语法是否正确
checkSyntax(script: string) { const contextKeys = Object.keys(this.context).join(',')
try { // 尝试创建一个新的函数,如果代码有语法错误,这里会抛出异常
new Function(contextKeys, `return (async () => { ${script} })();`) return null // 语法正确
} catch (error) { console.error('代码语法错误:', error) return error // 语法错误
} }
// 自动识别并提取动态JS执行块
extractDynamicJSBlocks(input: string): string[] { const regex = new RegExp( `${this.escapeRegExp(this.startDelimiter)}(.*?)${this.escapeRegExp(this.endDelimiter)}`, 'gs' )
const matches: string[] = [] let match
while ((match = regex.exec(input)) !== null) { matches.push(match[1].trim()) }
return matches }
// 执行所有提取的动态JS块
async execute(input: string): Promise<any[]> { const dynamicBlocks = this.extractDynamicJSBlocks(input) const results: any[] = []
for (const script of dynamicBlocks) { const contextKeys = Object.keys(this.context).join(',') const contextValues = Object.values(this.context)
const error = this.checkSyntax(script) if (error !== null) { throw error // 抛出异常以便在调用方捕获
}
const func = new Function(contextKeys, `return (async () => { ${script} })();`)
try { results.push(await func(...contextValues)) } catch (error) { this.handleError(error) throw error } }
return results }
private handleError(error: any) { console.log(`执行代码时发生错误: ${error.message}`) }
// 转义正则表达式中的特殊字符
private escapeRegExp(string: string): string { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') } }
// 创建一个默认的执行器实例
export const defaultExecutor = new DynamicScriptExecutor({
// 系统内置的一些全局对象
// 全局对象
console, setTimeout, setInterval, clearTimeout, clearInterval, fetch, location, React, // document,
FormData, URLSearchParams, Headers, Request, Response, Blob, FileReader, WebSocket, EventSource, localStorage, sessionStorage, indexedDB, crypto, performance, navigator, history, screen, alert, confirm, prompt, })
|