chore: 导入清理前的完整工程状态(含 Capacitor 原生壳,作为回滚备份点)

This commit is contained in:
toor
2026-10-21 11:50:10 +08:00
committed by trae-solo-agent
commit 8ded87a3a8
389 changed files with 52242 additions and 0 deletions
+67
View File
@@ -0,0 +1,67 @@
/**
* 巡检 packages/data/recipe.csv 中的 B 站视频是否失效,输出 Markdown 报告
*
* pnpm check:videos # 打印报告
* pnpm check:videos --out report.md # 同时写入文件(供 workflow 更新 issue)
*/
import fs from 'node:fs'
import process from 'node:process'
import { setTimeout as sleep } from 'node:timers/promises'
import { bilibiliViewApi, classifyBilibiliCode } from '../packages/cook/src/utils/bilibili'
import { recipeCsvFile } from '../packages/cook/src/utils/config'
import { parseRecipeCsv } from '../packages/cook/src/utils/csv'
const DELAY_MS = 400
async function check(id: string) {
try {
const res = await fetch(bilibiliViewApi(id), {
headers: { 'User-Agent': 'Mozilla/5.0 (cook recipe link checker; +https://github.com/YunYouJun/cook)' },
signal: AbortSignal.timeout(15_000),
})
const body = await res.json() as { code: number, message?: string }
return { status: classifyBilibiliCode(body.code), detail: `${body.code} ${body.message ?? ''}`.trim() }
}
catch (e) {
return { status: 'unknown' as const, detail: (e as Error).message }
}
}
const recipes = parseRecipeCsv(fs.readFileSync(recipeCsvFile, 'utf-8'))
const byVideo = new Map<string, { line: number, name: string }[]>()
recipes.forEach((recipe, i) => {
if (!recipe.bv)
return
const list = byVideo.get(recipe.bv) ?? []
list.push({ line: i + 2, name: recipe.name })
byVideo.set(recipe.bv, list)
})
const dead: string[] = []
let unknown = 0
for (const [id, uses] of byVideo) {
const result = await check(id)
if (result.status === 'dead') {
for (const use of uses)
dead.push(`| ${use.line} | ${use.name} | [${id}](https://www.bilibili.com/video/${id}) | ${result.detail} |`)
}
else if (result.status === 'unknown') {
unknown++
}
await sleep(DELAY_MS)
}
const report = [
`共检查 ${byVideo.size} 个视频,失效 ${dead.length} 条菜谱,无法确认 ${unknown} 个(接口限流或超时,下次巡检会重试)。`,
'',
...(dead.length
? ['| 行 | 菜名 | 视频 | 接口返回 |', '| --- | --- | --- | --- |', ...dead]
: ['没有发现失效视频。']),
'',
`_由 \`pnpm check:videos\` 生成于 ${new Date().toISOString().slice(0, 10)}。替换视频号或删除菜谱后,下一次巡检会自动更新此列表。_`,
].join('\n')
console.log(report)
const outIndex = process.argv.indexOf('--out')
if (outIndex > -1 && process.argv[outIndex + 1])
fs.writeFileSync(process.argv[outIndex + 1]!, report)