修复脚本导包

This commit is contained in:
mtvpls
2026-03-22 00:52:28 +08:00
parent 691247cb8e
commit 4bb6cd679d

View File

@@ -8,6 +8,10 @@ import { db } from '@/lib/db';
const SOURCE_SCRIPT_REGISTRY_KEY = 'source-script:registry';
const DEFAULT_TIMEOUT_MS = 20000;
// 绕过 webpack 静态分析,获取真正的 Node.js require
// eslint-disable-next-line no-eval
const _nodeRequire = eval('require') as NodeRequire;
// ---- 内存缓存 ----
let _registryCache: { data: SourceScriptRegistry; ts: number } | null = null;
const REGISTRY_CACHE_TTL_MS = 5_000;
@@ -188,24 +192,6 @@ function assertScriptKey(key: string) {
}
}
function assertSafeCode(code: string) {
const blockedPatterns = [
/\brequire\s*\(/,
/\bprocess\./,
/\bchild_process\b/,
/\bfs\b/,
/\bimport\s*\(/,
/\beval\s*\(/,
/\bnew\s+Function\b/,
];
for (const pattern of blockedPatterns) {
if (pattern.test(code)) {
throw new Error(`脚本包含不允许的用法: ${pattern}`);
}
}
}
function createLogCollector() {
const logs: string[] = [];
@@ -313,17 +299,10 @@ function createUtils() {
}
function createScriptFactory(code: string) {
assertSafeCode(code);
return new Function(
`"use strict";
const process = undefined;
const require = undefined;
const module = undefined;
const exports = undefined;
const fetch = undefined;
${code}`
) as () => any;
'require',
`"use strict";\n${code}`
) as (req: NodeRequire) => any;
}
async function createScriptContext(script: SourceScriptRecord, configValues?: Record<string, string>) {
@@ -462,7 +441,7 @@ function getOrCompileScript(script: SourceScriptRecord) {
if (cached) return cached;
const factory = createScriptFactory(script.code);
const compiled = normalizeScript(factory());
const compiled = normalizeScript(factory(_nodeRequire));
if (_compiledCache.size >= MAX_COMPILED_CACHE_SIZE) {
const firstKey = _compiledCache.keys().next().value;
@@ -550,7 +529,6 @@ export async function saveSourceScript(input: {
enabled?: boolean;
}) {
assertScriptKey(input.key);
assertSafeCode(input.code);
const registry = await loadRegistry();
const now = Date.now();
@@ -602,7 +580,6 @@ export async function importSourceScripts(items: SourceScriptImportItem[]) {
}
assertScriptKey(item.key);
assertSafeCode(item.code);
const existing = registry.items.find((record) => record.key === item.key);
@@ -682,7 +659,7 @@ export async function testSourceScript(input: {
};
const factory = createScriptFactory(input.code);
const compiled = normalizeScript(factory());
const compiled = normalizeScript(factory(_nodeRequire));
const hook = compiled[input.hook];
if (typeof hook !== 'function') {
throw new Error(`脚本未实现 ${input.hook} hook`);