94 lines
2.3 KiB
JavaScript
94 lines
2.3 KiB
JavaScript
|
|
#!/usr/bin/env node
|
|||
|
|
// scripts/hli-contract-check.js
|
|||
|
|
// HLI 接口契约校验 — 验证所有 schema 文件结构完整性
|
|||
|
|
// 版权:国作登字-2026-A-00037559
|
|||
|
|
|
|||
|
|
'use strict';
|
|||
|
|
|
|||
|
|
const fs = require('fs');
|
|||
|
|
const path = require('path');
|
|||
|
|
|
|||
|
|
const SCHEMA_DIR = path.resolve(__dirname, '../src/schemas/hli');
|
|||
|
|
|
|||
|
|
let passed = 0;
|
|||
|
|
let failed = 0;
|
|||
|
|
|
|||
|
|
function check(condition, message) {
|
|||
|
|
if (condition) {
|
|||
|
|
passed++;
|
|||
|
|
} else {
|
|||
|
|
failed++;
|
|||
|
|
console.error(` ❌ ${message}`);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log('🔍 HLI 接口契约校验\n');
|
|||
|
|
|
|||
|
|
// 扫描所有域目录
|
|||
|
|
const domains = fs.readdirSync(SCHEMA_DIR, { withFileTypes: true })
|
|||
|
|
.filter(d => d.isDirectory())
|
|||
|
|
.map(d => d.name);
|
|||
|
|
|
|||
|
|
for (const domain of domains) {
|
|||
|
|
const domainDir = path.join(SCHEMA_DIR, domain);
|
|||
|
|
const schemaFiles = fs.readdirSync(domainDir).filter(f => f.endsWith('.schema.json'));
|
|||
|
|
|
|||
|
|
for (const file of schemaFiles) {
|
|||
|
|
const filePath = path.join(domainDir, file);
|
|||
|
|
const relPath = `src/schemas/hli/${domain}/${file}`;
|
|||
|
|
|
|||
|
|
let schema;
|
|||
|
|
try {
|
|||
|
|
const content = fs.readFileSync(filePath, 'utf8');
|
|||
|
|
schema = JSON.parse(content);
|
|||
|
|
} catch (e) {
|
|||
|
|
failed++;
|
|||
|
|
console.error(` ❌ ${relPath}: JSON 解析失败 — ${e.message}`);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log(` 📋 ${relPath}`);
|
|||
|
|
|
|||
|
|
// 必须包含 hli_id
|
|||
|
|
check(
|
|||
|
|
typeof schema.hli_id === 'string' && schema.hli_id.startsWith('HLI-'),
|
|||
|
|
`${relPath}: 缺少有效的 hli_id`
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
// route 和 method:如存在则校验格式
|
|||
|
|
if (schema.route !== undefined) {
|
|||
|
|
check(
|
|||
|
|
typeof schema.route === 'string' && schema.route.startsWith('/hli/'),
|
|||
|
|
`${relPath}: route 格式无效(应以 /hli/ 开头)`
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (schema.method !== undefined) {
|
|||
|
|
check(
|
|||
|
|
typeof schema.method === 'string',
|
|||
|
|
`${relPath}: method 格式无效`
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 必须包含 input 和 output
|
|||
|
|
check(
|
|||
|
|
schema.input !== undefined,
|
|||
|
|
`${relPath}: 缺少 input 定义`
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
check(
|
|||
|
|
schema.output !== undefined,
|
|||
|
|
`${relPath}: 缺少 output 定义`
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log(`\n📊 契约校验: ${passed} 通过, ${failed} 失败`);
|
|||
|
|
|
|||
|
|
if (failed > 0) {
|
|||
|
|
console.error('❌ HLI Contract Check FAILED');
|
|||
|
|
process.exit(1);
|
|||
|
|
} else {
|
|||
|
|
console.log('✅ HLI Contract Check PASSED');
|
|||
|
|
}
|