const fs = require("node:fs"); const path = require("node:path"); const vm = require("node:vm"); const INPUT = "/Users/lanmu/Desktop/ai-chatbot-main/analysis/qiaodou-extract/extracted/assets/index-m-NWkaV-.js"; const OUTPUT_JSON = "/Users/lanmu/Desktop/ai-chatbot-main/analysis/qiaodou-extract/bundle-intel.json"; const source = fs.readFileSync(INPUT, "utf8"); function unique(values) { return Array.from(new Set(values)); } function safeEvalObjectLiteral(literal) { return vm.runInNewContext(`(${literal})`, Object.create(null), { timeout: 1000, }); } function extractBetween(startMarker, endMarker) { const start = source.indexOf(startMarker); if (start < 0) return null; const from = start + startMarker.length; const end = source.indexOf(endMarker, from); if (end < 0) return null; return source.slice(from, end); } function normalizeUrl(url) { return String(url || "").replace(/[.,;]+$/, "").trim(); } function isLikelyAppRelevantUrl(url) { if (!url || url === "http://" || url === "https://") return false; return !( url.includes("w3.org/") || url.includes("apache.org/") || url.includes("reactjs.org/") || url.includes("github.com/") || url.includes("raw.github.com/") || url.includes("developer.mozilla.org/") || url.includes("feross.org") || url.includes("stuk.github.io/") || url.includes("stuartk.com/jszip") ); } const storageKeys = unique( Array.from(source.matchAll(/qiaodoumayi_[A-Za-z0-9_]+/g)).map((match) => match[0]) ).sort(); const tauriCommands = unique( Array.from(source.matchAll(/yn\("([a-zA-Z0-9_:-]+)"/g)).map((match) => match[1]) ).sort(); const requireHints = unique( Array.from(source.matchAll(/\.\.\/[A-Za-z0-9_./-]+/g)).map((match) => match[0]) ).sort(); const allUrls = unique( Array.from(source.matchAll(/https?:\/\/[^\s"'`\\)<>,]+/g)).map((match) => normalizeUrl(match[0])) ).sort(); const appRelevantUrls = allUrls.filter(isLikelyAppRelevantUrl); const domains = unique( appRelevantUrls .map((url) => { try { return new URL(url).host; } catch { return null; } }) .filter(Boolean) ).sort(); let quickConnectConfig = {}; const quickConnectLiteral = extractBetween("DV=", ";function npe"); if (quickConnectLiteral) { quickConnectConfig = safeEvalObjectLiteral(quickConnectLiteral); } let nodeLabelMap = {}; const nodeLabelMatch = source.match(/function Rm\(e\)\{return(\{[\s\S]*?\})\[e\]\|\|"节点"\}/); if (nodeLabelMatch) { nodeLabelMap = safeEvalObjectLiteral(nodeLabelMatch[1]); } const nodeSizeMap = {}; const nodeSizeMatch = source.match(/function jO\(e\)\{switch\(e\)\{([\s\S]*?)default:return\{w:(\d+),h:(\d+)\}\}\}/); if (nodeSizeMatch) { const body = nodeSizeMatch[1]; const defaultSize = { w: Number(nodeSizeMatch[2]), h: Number(nodeSizeMatch[3]) }; nodeSizeMap.default = defaultSize; const groupedCases = body.matchAll(/((?:case"[^"]+":)+)return\{w:(\d+),h:(\d+)\}/g); for (const groupedCase of groupedCases) { const labels = Array.from(groupedCase[1].matchAll(/case"([^"]+)":/g)).map((match) => match[1]); const size = { w: Number(groupedCase[2]), h: Number(groupedCase[3]) }; for (const label of labels) { nodeSizeMap[label] = size; } } } const quickConnectTypes = Object.keys(quickConnectConfig); const nodeTypes = unique([ ...Object.keys(nodeLabelMap), ...Object.keys(nodeSizeMap).filter((key) => key !== "default"), ...quickConnectTypes, ...quickConnectTypes.flatMap((type) => (quickConnectConfig[type]?.output || []).map((item) => item.type) ), ]).sort(); const nodeCatalog = nodeTypes.map((type) => ({ type, label: nodeLabelMap[type] || null, size: nodeSizeMap[type] || nodeSizeMap.default || null, quickConnectOutputs: (quickConnectConfig[type]?.output || []).map((item) => ({ type: item.type, label: item.label, })), })); const indexedDb = { databaseName: source.includes('"qiaodoumayi_projects"') ? "qiaodoumayi_projects" : null, version: source.includes('qiaodoumayi_projects",Ioe=2') ? 2 : null, stores: unique( Array.from(source.matchAll(/"(project_meta|project_payload|project_assets)"/g)).map( (match) => match[1] ) ), }; const snippets = {}; for (const term of [ "qiaodoumayi_seedance_moderation_url", "download_file_bypass_cors", "start_local_server", "qiaodoumayi_projects", "qiaodoumayi_script_projects", "qiaodoumayi_saved_skills", "qiaodoumayi_characters", "https://ai.comfly.chat/sora/v1/characters", "https://www.runninghub.cn", ]) { const index = source.indexOf(term); snippets[term] = index >= 0 ? { index, preview: source.slice(Math.max(0, index - 180), Math.min(source.length, index + 260)), } : null; } const result = { input: INPUT, stats: { bytes: Buffer.byteLength(source, "utf8"), lines: source.split("\n").length, hasSourceMap: /sourceMappingURL/.test(source), }, storageKeys, tauriCommands, requireHints, urls: { appRelevant: appRelevantUrls, all: allUrls, domains, }, indexedDb, quickConnectConfig, nodeLabelMap, nodeSizeMap, nodeCatalog, snippets, }; fs.writeFileSync(OUTPUT_JSON, `${JSON.stringify(result, null, 2)}\n`); console.log(`Wrote ${OUTPUT_JSON}`);