| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- /**
- * 审计所有 api-config.json 的 endpoint 路径 vs 当前配置的 apigId
- * 规则:
- * /api/voc-social/* → apigId=Vo3ROWEvDy
- * /api/voc-ecom/forward/* → apigId=7HwdQZk55B
- * /api/volcengine/jimeng/* → apigId=? (暂标未知)
- * 其他 → 打印出来让人工判断
- */
- const fs = require('fs');
- const path = require('path');
- const ROOT = path.resolve(__dirname, '..', '..');
- const EXPECTED = {
- '/api/voc-social/': 'Vo3ROWEvDy',
- '/api/voc-ecom/': '7HwdQZk55B',
- };
- function walk(d, r = []) {
- for (const e of fs.readdirSync(d, { withFileTypes: true })) {
- if (e.name === 'node_modules' || e.name === '.git' || e.name === 'dist') continue;
- const p = path.join(d, e.name);
- if (e.isDirectory()) walk(p, r);
- else if (e.name === 'api-config.json') r.push(p);
- }
- return r;
- }
- const files = walk(ROOT);
- const results = { match: [], mismatch: [], orchestration: [], unknown: [] };
- for (const f of files) {
- let cfg;
- try { cfg = JSON.parse(fs.readFileSync(f, 'utf-8')); } catch { continue; }
- const curApigId = cfg.tokenConfig?.apigId || null;
- const rel = path.relative(ROOT, f).replace(/\\/g, '/');
- // 直接 endpoint
- const url = cfg.endpoint?.url;
- if (url) {
- const u = new URL(url);
- const pathOnly = u.pathname;
- let expected = null;
- for (const [prefix, apig] of Object.entries(EXPECTED)) {
- if (pathOnly.startsWith(prefix)) { expected = apig; break; }
- }
- if (expected) {
- if (curApigId === expected) {
- results.match.push({ file: rel, pathOnly, apigId: curApigId });
- } else {
- results.mismatch.push({ file: rel, pathOnly, current: curApigId, expected });
- }
- } else {
- results.unknown.push({ file: rel, pathOnly, current: curApigId });
- }
- continue;
- }
- // orchestration 型:检查 pipeline steps 的 endpoint
- const steps = cfg.pipeline || [];
- const stepUrls = [];
- function collectUrls(node) {
- if (!node || typeof node !== 'object') return;
- if (Array.isArray(node)) return node.forEach(collectUrls);
- if (node.endpoint && typeof node.endpoint === 'string') stepUrls.push(node.endpoint);
- for (const v of Object.values(node)) collectUrls(v);
- }
- collectUrls(steps);
- if (stepUrls.length > 0) {
- const pathsFound = stepUrls.map(u => { try { return new URL(u).pathname; } catch { return u; } });
- const distinct = [...new Set(pathsFound.map(p => {
- for (const prefix of Object.keys(EXPECTED)) if (p.startsWith(prefix)) return prefix;
- return p;
- }))];
- results.orchestration.push({ file: rel, current: curApigId, distinctPathPrefixes: distinct });
- }
- }
- console.log('\n═════════════════════════ 审计结果 ═════════════════════════\n');
- console.log(`✅ apigId 正确 (${results.match.length})`);
- const byApig = {};
- results.match.forEach(m => { byApig[m.apigId] = (byApig[m.apigId] || 0) + 1; });
- console.log(' 分布:', JSON.stringify(byApig));
- console.log(`\n❌ apigId 错误 (${results.mismatch.length})`);
- results.mismatch.forEach(m => {
- console.log(` ${m.file}`);
- console.log(` 当前=${m.current} 应该=${m.expected} path=${m.pathOnly}`);
- });
- console.log(`\n⚠️ orchestration (pipeline) 类 (${results.orchestration.length})`);
- results.orchestration.forEach(o => {
- console.log(` ${o.file} current=${o.current} paths=${JSON.stringify(o.distinctPathPrefixes)}`);
- });
- console.log(`\n❓ 未知路径 (${results.unknown.length})`);
- results.unknown.forEach(u => {
- console.log(` ${u.file} current=${u.current} path=${u.pathOnly}`);
- });
|