20261007220117

This commit is contained in:
oneao committed 2026-10-07 22:01:17 +08:00
1 parent 9217b3fa42
commit 8b1ec67609
275 files changed
+20026 -49299

No files matched your search

+95
View File
@@ -0,0 +1,95 @@
#!/usr/bin/env node
/**
* 从组件源码生成 API 数据。
*
* 用 vue-docgen-api 解析 packages/ui/src 下的 .vue 文件,
* 提取 props / events / slots 及其 JSDoc 注释,输出到 docs/data/api/<组件名>.json,
* 由文档站的 <ApiTable> 组件读取渲染。
*
* 这样 API 表格永远与源码一致,禁止手写。
* 源码改动后执行:pnpm gen:api
*/
import { mkdir, readdir, writeFile } from 'node:fs/promises'
import { basename, dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import { parse } from 'vue-docgen-api'
const root = fileURLToPath(new URL('..', import.meta.url))
const uiSrc = join(root, 'packages/ui/src')
const outDir = join(root, 'docs/data/api')
/** 递归收集所有 .vue 组件文件 */
async function findComponents(dir) {
const found = []
for (const entry of await readdir(dir, { withFileTypes: true })) {
const full = join(dir, entry.name)
if (entry.isDirectory()) {
found.push(...(await findComponents(full)))
} else if (entry.name.endsWith('.vue')) {
found.push(full)
}
}
return found
}
/** packages/ui/src/button/Button.vue -> button */
function toKey(file) {
return basename(dirname(file))
}
/** docgen 给出的值可能带引号,统一剥掉 */
function clean(text = '') {
return String(text).replace(/^['"]|['"]$/g, '')
}
/** 把说明文字压成单行,避免表格里出现换行 */
function oneLine(text = '') {
return String(text).replace(/\s+/g, ' ').trim()
}
function mapMember(item) {
return {
name: item.name,
description: oneLine(item.description),
type: item.type?.name ?? '',
defaultValue: item.defaultValue ? clean(item.defaultValue.value) : '',
}
}
async function main() {
const files = await findComponents(uiSrc)
const results = []
for (const file of files) {
const info = await parse(file)
const key = toKey(file)
results.push([
key,
{
displayName: info.displayName || key,
description: oneLine(info.description),
props: (info.props ?? []).map(mapMember),
events: (info.events ?? []).map(mapMember),
slots: (info.slots ?? []).map((slot) => ({
name: slot.name,
description: oneLine(slot.description),
})),
},
])
}
await mkdir(outDir, { recursive: true })
for (const [key, doc] of results) {
await writeFile(join(outDir, `${key}.json`), `${JSON.stringify(doc, null, 2)}\n`, 'utf-8')
console.log(
`✓ ${key.padEnd(12)} props=${doc.props.length} events=${doc.events.length} slots=${doc.slots.length}`,
)
}
}
main().catch((error) => {
console.error('[gen-api] 失败:', error)
process.exit(1)
})