import { readFileSync } from 'node:fs'; import { dirname, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; const root = resolve(dirname(fileURLToPath(import.meta.url)), '..'); const source = readFileSync(resolve(root, 'src/api/resources.ts'), 'utf8'); const routes = readFileSync(resolve(root, 'src/router/routes/modules/platform.ts'), 'utf8'); const contract = JSON.parse( readFileSync(resolve(root, 'src/contracts/platform-resources.json'), 'utf8'), ); const backend = new Map(contract.resources.map((item) => [item.name, item])); const frontendNames = [...source.matchAll(/define\('([^']+)'/g)].map((match) => match[1]); for (const name of frontendNames) { const item = backend.get(name); if (!item) throw new Error(`前端配置了后端不存在的资源:${name}`); if (item.path !== `/${name}`) throw new Error(`资源路径不一致:${name}`); } for (const item of contract.resources) { if (!frontendNames.includes(item.name)) throw new Error(`缺少后端资源配置:${item.name}`); } const forbidden = [ '/platform/platform_', '/gas/gas_', '/delivery/delivery_', '/staff/', '/user/', '/ec/ec_', '/finance/fin_', '/wallet/wallet', 'delivery_task', 'delivery_track', 'delivery_track_point', 'dev_device_binding', 'dev_smart_cylinder_valve', 'dev_telemetry', 'wallet_ledger', 'wallet_recharge', 'wallet_withdrawal', ]; for (const value of forbidden) { if (source.includes(value) || routes.includes(value)) throw new Error(`仍存在旧资源或旧路径:${value}`); } console.log(`契约检查通过:${frontendNames.length} 个资源`);