chore: 安全升级并完善 CI/测试

- 升级 js-yaml 修复生产依赖漏洞
- 新增 CI:lint/test/build
- 增加书签处理单测与可测性导出"- 生成器补充 config/user 缺失提示
- 增加 lint/format/check 脚本与 Prettier 配置
- 统一行尾策略并支持书签确定性输出"
This commit is contained in:
rbetree
2025-12-22 00:44:51 +08:00
parent 7a7bf361e3
commit 47e4369b09
11 changed files with 286 additions and 18 deletions

View File

@@ -714,11 +714,15 @@ function generateBookmarksYaml(bookmarks) {
quotingType: '"'
});
// 添加注释
const yamlWithComment =
// 添加注释(可选确定性输出,方便版本管理)
const deterministic = process.env.MENAV_BOOKMARKS_DETERMINISTIC === '1';
const timestampLine = deterministic
? ''
: `# 由bookmark-processor.js生成于 ${new Date().toISOString()}\n`;
const yamlWithComment =
`# 自动生成的书签配置文件
# 由bookmark-processor.js生成于 ${new Date().toISOString()}
# 若要更新请将新的书签HTML文件放入bookmarks/目录
${timestampLine}# 若要更新请将新的书签HTML文件放入bookmarks/目录
# 此文件使用模块化配置格式位于config/user/pages/目录下
${yamlString}`;
@@ -914,4 +918,13 @@ if (require.main === module) {
console.error('Unhandled error in bookmark processing:', err);
process.exit(1);
});
}
}
module.exports = {
ensureUserConfigInitialized,
ensureUserSiteYmlExists,
upsertBookmarksNavInSiteYml,
parseBookmarks,
generateBookmarksYaml,
updateNavigationWithBookmarks,
};

View File

@@ -519,6 +519,19 @@ function loadConfig() {
// 根据优先级顺序选择最高优先级的配置
if (hasUserModularConfig) {
// 配置采用“完全替换”策略:一旦存在 config/user/,将不会回退到 config/_default/
if (!fs.existsSync('config/user/site.yml')) {
console.error('[ERROR] 检测到 config/user/ 目录,但缺少 config/user/site.yml。');
console.error('[ERROR] 由于配置采用“完全替换”策略,系统不会从 config/_default/ 补齐缺失配置。');
console.error('[ERROR] 解决方法:先完整复制 config/_default/ 到 config/user/,再按需修改。');
process.exit(1);
}
if (!fs.existsSync('config/user/pages')) {
console.warn('[WARN] 检测到 config/user/ 目录,但缺少 config/user/pages/。部分页面内容可能为空。');
console.warn('[WARN] 建议:复制 config/_default/pages/ 到 config/user/pages/,再按需修改。');
}
// 1. 最高优先级: config/user/ 目录
config = loadModularConfig('config/user');
} else if (hasDefaultModularConfig) {