Files
platforms/frontend/platform_admin/scripts/check-backend-contract.mjs

79 lines
2.5 KiB
JavaScript
Raw Normal View History

/**
* 功能校验平台总后台资源定义页面路由与后端资源契约保持一致
* 版本v1.1.0
*/
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 routeFiles = ['platform.ts', 'finance-route.ts'];
const routes = routeFiles
.map((name) =>
readFileSync(resolve(root, 'src/router/routes/modules', name), 'utf8'),
)
.join('\n');
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 frontendDefinitions = [
...source.matchAll(
/define\(\s*'([^']+)'\s*,\s*'[^']+'\s*,\s*'([^']+)'/g,
),
].map((match) => ({ name: match[1], mode: match[2] }));
const frontendNames = frontendDefinitions.map((item) => item.name);
const embeddedResources = new Set([
'wallet_basic',
'wallet_bank',
'payment_order',
'wallet_record',
'payment_refund',
'wallet_apply_cash',
]);
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 frontend = frontendDefinitions.find(
(definition) => definition.name === item.name,
);
if (frontend?.mode !== item.mode)
throw new Error(
`资源模式不一致:${item.name},后端=${item.mode},前端=${frontend?.mode}`,
);
if (!embeddedResources.has(item.name) && !routes.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} 个资源`);