feat: 开源项目门户站首版(iotLCM / 秀杰 DTU / XiuAdmin 三项目,注册表驱动)
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* 校验「项目注册表」与「详情页目录」是否一一对应。
|
||||
*
|
||||
* 门户的项目清单由 data/projects.ts 单一驱动。如果注册表加了项目却忘了写详情页,
|
||||
* 或者写了详情页却没登记进注册表,首页卡片与侧边栏就会和实际内容脱节。
|
||||
* 这个脚本在 dev / build 之前自动跑,不一致直接退出非零。
|
||||
*/
|
||||
import { readdirSync, readFileSync, existsSync } from 'node:fs'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { dirname, join } from 'node:path'
|
||||
|
||||
const root = join(dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const dataDir = join(root, 'data')
|
||||
const pagesDir = join(root, 'pages', 'projects')
|
||||
|
||||
// 注册表是 TS 源文件,这里只需要 id 列表,正则抽取即可,不引入编译步骤
|
||||
const registrySrc = readdirSync(dataDir)
|
||||
.filter((f) => f.endsWith('.ts'))
|
||||
.map((f) => readFileSync(join(dataDir, f), 'utf-8'))
|
||||
.join('\n')
|
||||
|
||||
const registered = [...registrySrc.matchAll(/\bid:\s*'([^']+)'/g)].map((m) => m[1])
|
||||
|
||||
if (registered.length === 0) {
|
||||
console.error('[check] 注册表里没解析到任何项目,检查 data/projects.ts 的格式')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const onDisk = existsSync(pagesDir)
|
||||
? readdirSync(pagesDir, { withFileTypes: true })
|
||||
.filter((d) => d.isDirectory())
|
||||
.map((d) => d.name)
|
||||
: []
|
||||
|
||||
const missingPages = registered.filter((id) => !onDisk.includes(id))
|
||||
const missingEntries = onDisk.filter((id) => !registered.includes(id))
|
||||
|
||||
if (missingPages.length || missingEntries.length) {
|
||||
if (missingPages.length) {
|
||||
console.error(`[check] 注册表里有项目但缺详情页:${missingPages.join(', ')}`)
|
||||
}
|
||||
if (missingEntries.length) {
|
||||
console.error(`[check] 有详情页但没登记进注册表:${missingEntries.join(', ')}`)
|
||||
}
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log(`[check] OK:注册表 ${registered.length} 个项目与详情页一一对应(${registered.join(', ')})`)
|
||||
Reference in New Issue
Block a user