#!/usr/bin/env node import process from "node:process"; const baseUrl = normalizeBaseUrl(process.argv[2] ?? process.env.PUBLIC_BASE_URL ?? process.env.LIVE_SMOKE_BASE_URL ?? "https://oa.hyinda.com"); const focusedAssetPattern = /(MobileReimbursementDetailPage|ReimbursementDetailPage|page-mobile|page-assets|page-travel)/; const forbiddenTerms = ["绑定整单", "不绑定明细", "识别完成后可在", "发票池", "OCR"]; function normalizeBaseUrl(value) { return String(value).replace(/\/+$/, ""); } function toAssetPath(value) { if (value.startsWith("/")) { return value; } return `/assets/${value.replace(/^\.\//, "")}`; } async function fetchText(path) { const response = await fetch(`${baseUrl}${path}`); if (!response.ok) { throw new Error(`GET ${path} failed: ${response.status}`); } return response.text(); } async function collectAssets() { const seen = new Set(); const queue = []; const html = await fetchText("/"); for (const match of html.matchAll(/(?:src|href)=["'](\/assets\/[^"']+\.js)["']/g)) { const assetPath = toAssetPath(match[1]); if (!seen.has(assetPath)) { queue.push(assetPath); seen.add(assetPath); } } for (let index = 0; index < queue.length; index += 1) { const assetPath = queue[index]; const source = await fetchText(assetPath); for (const match of source.matchAll(/\.\/([A-Za-z0-9_./-]+\.js)/g)) { const nextPath = toAssetPath(match[1]); if (!seen.has(nextPath)) { queue.push(nextPath); seen.add(nextPath); } } } return Array.from(seen).sort(); } const assets = await collectAssets(); const findings = []; for (const assetPath of assets) { if (!focusedAssetPattern.test(assetPath)) { continue; } const source = await fetchText(assetPath); for (const term of forbiddenTerms) { if (source.includes(term)) { findings.push({ assetPath, term }); } } } console.log(`[public-bundle-copy] base=${baseUrl} scanned=${assets.length} focused=${assets.filter((item) => focusedAssetPattern.test(item)).length} findings=${findings.length}`); for (const finding of findings) { console.log(`ERROR ${finding.assetPath} contains ${finding.term}`); } if (findings.length) { process.exitCode = 1; }