更新模块化配置支持
This commit is contained in:
@@ -6,8 +6,12 @@ const yaml = require('js-yaml');
|
||||
const BOOKMARKS_DIR = 'bookmarks';
|
||||
// 输出配置文件路径 - 使用相对路径
|
||||
const OUTPUT_FILE = 'bookmarks.user.yml';
|
||||
// 模块化输出配置文件路径
|
||||
const MODULAR_OUTPUT_FILE = 'config/user/pages/bookmarks.yml';
|
||||
// 默认书签配置文件路径 - 使用相对路径
|
||||
const DEFAULT_BOOKMARKS_FILE = 'bookmarks.yml';
|
||||
// 模块化默认书签配置文件路径
|
||||
const MODULAR_DEFAULT_BOOKMARKS_FILE = 'config/_default/pages/bookmarks.yml';
|
||||
|
||||
// 图标映射,根据URL关键字匹配合适的图标
|
||||
const ICON_MAPPING = {
|
||||
@@ -209,20 +213,114 @@ ${yamlString}`;
|
||||
|
||||
// 更新现有config.yml中的导航,添加书签页面
|
||||
function updateConfigWithBookmarks() {
|
||||
// 传统配置文件
|
||||
const configFile = 'config.yml';
|
||||
const userConfigFile = 'config.user.yml';
|
||||
|
||||
// 优先使用用户配置文件,如果存在
|
||||
const targetConfigFile = fs.existsSync(userConfigFile) ? userConfigFile : configFile;
|
||||
// 模块化配置文件
|
||||
const modularNavFile = 'config/_default/navigation.yml';
|
||||
const modularUserNavFile = 'config/user/navigation.yml';
|
||||
|
||||
let navigationUpdated = false;
|
||||
|
||||
// 按优先级顺序尝试更新导航配置
|
||||
|
||||
// 1. 最高优先级: 模块化用户导航配置
|
||||
if (fs.existsSync(modularUserNavFile)) {
|
||||
navigationUpdated = updateNavigationFile(modularUserNavFile);
|
||||
if (navigationUpdated) {
|
||||
console.log(`Updated modular user navigation file: ${modularUserNavFile} (highest priority)`);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 次高优先级: 传统用户配置
|
||||
if (!navigationUpdated && fs.existsSync(userConfigFile)) {
|
||||
navigationUpdated = updateTraditionalConfig(userConfigFile);
|
||||
if (navigationUpdated) {
|
||||
console.log(`Updated legacy user config file: ${userConfigFile}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 次低优先级: 模块化默认导航
|
||||
if (!navigationUpdated && fs.existsSync(modularNavFile)) {
|
||||
navigationUpdated = updateNavigationFile(modularNavFile);
|
||||
if (navigationUpdated) {
|
||||
console.log(`Updated modular default navigation file: ${modularNavFile}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 最低优先级: 传统默认配置
|
||||
if (!navigationUpdated && fs.existsSync(configFile)) {
|
||||
navigationUpdated = updateTraditionalConfig(configFile);
|
||||
if (navigationUpdated) {
|
||||
console.log(`Updated legacy default config file: ${configFile} (lowest priority)`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!navigationUpdated) {
|
||||
console.log('Did not find any configuration file to update with bookmarks navigation');
|
||||
}
|
||||
}
|
||||
|
||||
// 更新单个导航配置文件(模块化版本)
|
||||
function updateNavigationFile(filePath) {
|
||||
try {
|
||||
const configContent = fs.readFileSync(targetConfigFile, 'utf8');
|
||||
const content = fs.readFileSync(filePath, 'utf8');
|
||||
const navConfig = yaml.load(content);
|
||||
|
||||
// 检查是否已有书签页面
|
||||
const hasBookmarksNav = Array.isArray(navConfig) &&
|
||||
navConfig.some(nav => nav.id === 'bookmarks');
|
||||
|
||||
if (!hasBookmarksNav) {
|
||||
// 添加书签导航项
|
||||
if (!Array.isArray(navConfig)) {
|
||||
console.log(`Warning: Navigation config in ${filePath} is not an array, cannot update`);
|
||||
return false;
|
||||
}
|
||||
|
||||
navConfig.push({
|
||||
name: '书签',
|
||||
icon: 'fas fa-bookmark',
|
||||
id: 'bookmarks',
|
||||
active: false
|
||||
});
|
||||
|
||||
// 更新文件
|
||||
const updatedYaml = yaml.dump(navConfig, {
|
||||
indent: 2,
|
||||
lineWidth: -1,
|
||||
quotingType: '"'
|
||||
});
|
||||
|
||||
fs.writeFileSync(filePath, updatedYaml, 'utf8');
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // 无需更新
|
||||
} catch (error) {
|
||||
console.error(`Error updating navigation file ${filePath}:`, error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新传统配置文件(整体配置)
|
||||
function updateTraditionalConfig(filePath) {
|
||||
try {
|
||||
const configContent = fs.readFileSync(filePath, 'utf8');
|
||||
const config = yaml.load(configContent);
|
||||
|
||||
// 检查导航中是否已有书签页面
|
||||
const hasBookmarksNav = config.navigation.some(nav => nav.id === 'bookmarks');
|
||||
const hasBookmarksNav = config.navigation &&
|
||||
Array.isArray(config.navigation) &&
|
||||
config.navigation.some(nav => nav.id === 'bookmarks');
|
||||
|
||||
if (!hasBookmarksNav) {
|
||||
// 确保navigation数组存在
|
||||
if (!config.navigation) {
|
||||
config.navigation = [];
|
||||
}
|
||||
|
||||
// 添加书签页面到导航
|
||||
config.navigation.push({
|
||||
name: '书签',
|
||||
@@ -238,11 +336,14 @@ function updateConfigWithBookmarks() {
|
||||
quotingType: '"'
|
||||
});
|
||||
|
||||
fs.writeFileSync(targetConfigFile, updatedYaml, 'utf8');
|
||||
console.log(`Updated ${targetConfigFile} with bookmarks navigation`);
|
||||
fs.writeFileSync(filePath, updatedYaml, 'utf8');
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; // 无需更新
|
||||
} catch (error) {
|
||||
console.error('Error updating config with bookmarks navigation:', error);
|
||||
console.error(`Error updating config file ${filePath}:`, error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +351,8 @@ function updateConfigWithBookmarks() {
|
||||
async function main() {
|
||||
console.log('Starting bookmark processing...');
|
||||
console.log(`Current working directory: ${process.cwd()}`);
|
||||
console.log(`Output file will be: ${OUTPUT_FILE} (absolute: ${path.resolve(OUTPUT_FILE)})`);
|
||||
console.log(`Legacy output file will be: ${OUTPUT_FILE} (absolute: ${path.resolve(OUTPUT_FILE)})`);
|
||||
console.log(`Modular output file will be: ${MODULAR_OUTPUT_FILE} (absolute: ${path.resolve(MODULAR_OUTPUT_FILE)})`);
|
||||
|
||||
// 获取最新的书签文件
|
||||
const bookmarkFile = getLatestBookmarkFile();
|
||||
@@ -288,39 +390,58 @@ async function main() {
|
||||
console.log(yaml.split('\n').slice(0, 5).join('\n') + '\n...');
|
||||
|
||||
try {
|
||||
// 确保目标目录存在
|
||||
// 确保传统目标目录存在
|
||||
const outputDir = path.dirname(OUTPUT_FILE);
|
||||
if (!fs.existsSync(outputDir) && outputDir !== '.') {
|
||||
console.log(`Creating output directory: ${outputDir}`);
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
}
|
||||
|
||||
// 保存YAML文件
|
||||
console.log(`Writing to: ${OUTPUT_FILE}`);
|
||||
// 确保模块化目标目录存在
|
||||
const modularOutputDir = path.dirname(MODULAR_OUTPUT_FILE);
|
||||
if (!fs.existsSync(modularOutputDir)) {
|
||||
console.log(`Creating modular output directory structure: ${modularOutputDir}`);
|
||||
fs.mkdirSync(modularOutputDir, { recursive: true });
|
||||
}
|
||||
|
||||
// 保存YAML到传统位置
|
||||
console.log(`Writing to legacy location: ${OUTPUT_FILE}`);
|
||||
fs.writeFileSync(OUTPUT_FILE, yaml, 'utf8');
|
||||
|
||||
// 保存YAML到模块化位置
|
||||
console.log(`Writing to modular location: ${MODULAR_OUTPUT_FILE}`);
|
||||
fs.writeFileSync(MODULAR_OUTPUT_FILE, yaml, 'utf8');
|
||||
|
||||
// 验证文件是否确实被创建
|
||||
let success = false;
|
||||
|
||||
if (fs.existsSync(OUTPUT_FILE)) {
|
||||
const stats = fs.statSync(OUTPUT_FILE);
|
||||
console.log(`Successfully saved bookmarks configuration to ${OUTPUT_FILE}`);
|
||||
console.log(`Verified file exists: ${OUTPUT_FILE}`);
|
||||
console.log(`File size: ${stats.size} bytes`);
|
||||
console.log(`File permissions: ${stats.mode.toString(8)}`);
|
||||
|
||||
// 列出当前目录内容以确认
|
||||
console.log('Current directory contains:');
|
||||
fs.readdirSync('.').forEach(file => {
|
||||
console.log(`- ${file}`);
|
||||
});
|
||||
success = true;
|
||||
} else {
|
||||
console.error(`ERROR: File was not created: ${OUTPUT_FILE}`);
|
||||
console.error(`ERROR: Legacy file was not created: ${OUTPUT_FILE}`);
|
||||
}
|
||||
|
||||
if (fs.existsSync(MODULAR_OUTPUT_FILE)) {
|
||||
const stats = fs.statSync(MODULAR_OUTPUT_FILE);
|
||||
console.log(`Successfully saved bookmarks configuration to ${MODULAR_OUTPUT_FILE}`);
|
||||
console.log(`File size: ${stats.size} bytes`);
|
||||
success = true;
|
||||
} else {
|
||||
console.error(`ERROR: Modular file was not created: ${MODULAR_OUTPUT_FILE}`);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
console.error('ERROR: No output files were created successfully');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 更新导航
|
||||
updateConfigWithBookmarks();
|
||||
} catch (writeError) {
|
||||
console.error(`ERROR writing file ${OUTPUT_FILE}:`, writeError);
|
||||
console.error(`ERROR writing files:`, writeError);
|
||||
process.exit(1);
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
201
src/generator.js
201
src/generator.js
@@ -15,48 +15,199 @@ function escapeHtml(unsafe) {
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
// 读取配置文件
|
||||
function loadConfig() {
|
||||
let config = null;
|
||||
|
||||
try {
|
||||
// 优先尝试读取用户配置
|
||||
if (fs.existsSync('config.user.yml')) {
|
||||
const userConfigFile = fs.readFileSync('config.user.yml', 'utf8');
|
||||
config = yaml.load(userConfigFile);
|
||||
console.log('Using user configuration from config.user.yml');
|
||||
}
|
||||
// 如果没有用户配置,则使用默认配置
|
||||
else {
|
||||
const defaultConfigFile = fs.readFileSync('config.yml', 'utf8');
|
||||
config = yaml.load(defaultConfigFile);
|
||||
console.log('No user configuration found, using default config.yml');
|
||||
/**
|
||||
* 从文件合并配置到主配置对象
|
||||
* @param {Object} config 主配置对象
|
||||
* @param {string} filePath 配置文件路径
|
||||
*/
|
||||
function mergeConfigFromFile(config, filePath) {
|
||||
if (fs.existsSync(filePath)) {
|
||||
try {
|
||||
const fileContent = fs.readFileSync(filePath, 'utf8');
|
||||
const fileConfig = yaml.load(fileContent);
|
||||
|
||||
// 提取文件名(不含扩展名)作为配置键
|
||||
const configKey = path.basename(filePath, path.extname(filePath));
|
||||
|
||||
// 如果是site或navigation文件,直接合并到主配置
|
||||
if (configKey === 'site' || configKey === 'navigation') {
|
||||
if (!config[configKey]) config[configKey] = {};
|
||||
deepMerge(config[configKey], fileConfig);
|
||||
} else {
|
||||
// 其他配置直接合并到根级别
|
||||
deepMerge(config, fileConfig);
|
||||
}
|
||||
|
||||
console.log(`Loaded and merged configuration from ${filePath}`);
|
||||
} catch (e) {
|
||||
console.error(`Error loading configuration from ${filePath}:`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载页面配置目录中的所有配置文件
|
||||
* @param {Object} config 主配置对象
|
||||
* @param {string} dirPath 页面配置目录路径
|
||||
*/
|
||||
function loadPageConfigs(config, dirPath) {
|
||||
if (fs.existsSync(dirPath)) {
|
||||
const files = fs.readdirSync(dirPath).filter(file =>
|
||||
file.endsWith('.yml') || file.endsWith('.yaml'));
|
||||
|
||||
files.forEach(file => {
|
||||
try {
|
||||
const filePath = path.join(dirPath, file);
|
||||
const fileContent = fs.readFileSync(filePath, 'utf8');
|
||||
const fileConfig = yaml.load(fileContent);
|
||||
|
||||
// 提取文件名(不含扩展名)作为配置键
|
||||
const configKey = path.basename(file, path.extname(file));
|
||||
|
||||
// 将页面配置添加到主配置对象
|
||||
config[configKey] = fileConfig;
|
||||
|
||||
console.log(`Loaded page configuration from ${filePath}`);
|
||||
} catch (e) {
|
||||
console.error(`Error loading page configuration from ${path.join(dirPath, file)}:`, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 深度合并两个对象
|
||||
* @param {Object} target 目标对象
|
||||
* @param {Object} source 源对象
|
||||
* @returns {Object} 合并后的对象
|
||||
*/
|
||||
function deepMerge(target, source) {
|
||||
if (!source) return target;
|
||||
|
||||
for (const key in source) {
|
||||
if (source.hasOwnProperty(key)) {
|
||||
if (typeof source[key] === 'object' && source[key] !== null) {
|
||||
// 确保目标对象有这个属性
|
||||
if (!target[key]) {
|
||||
if (Array.isArray(source[key])) {
|
||||
target[key] = [];
|
||||
} else {
|
||||
target[key] = {};
|
||||
}
|
||||
}
|
||||
|
||||
// 递归合并
|
||||
if (Array.isArray(source[key])) {
|
||||
// 对于数组,直接替换或添加
|
||||
target[key] = source[key];
|
||||
} else {
|
||||
// 对于对象,递归合并
|
||||
deepMerge(target[key], source[key]);
|
||||
}
|
||||
} else {
|
||||
// 对于基本类型,直接替换
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error loading configuration file:', e);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 尝试读取书签配置
|
||||
return target;
|
||||
}
|
||||
|
||||
// 读取配置文件
|
||||
function loadConfig() {
|
||||
// 初始化空配置对象
|
||||
let config = {
|
||||
site: {},
|
||||
navigation: [],
|
||||
fonts: {},
|
||||
profile: {},
|
||||
social: [],
|
||||
categories: []
|
||||
};
|
||||
|
||||
// 处理配置目录结构,按照优先级从低到高加载
|
||||
// 4. 最低优先级: config.yml (传统默认配置)
|
||||
if (fs.existsSync('config.yml')) {
|
||||
const defaultConfigFile = fs.readFileSync('config.yml', 'utf8');
|
||||
const defaultConfig = yaml.load(defaultConfigFile);
|
||||
deepMerge(config, defaultConfig);
|
||||
console.log('Loaded legacy default config.yml');
|
||||
}
|
||||
|
||||
// 3. 其次优先级: config/_default/ 目录
|
||||
if (fs.existsSync('config/_default')) {
|
||||
console.log('Loading modular default configuration from config/_default/');
|
||||
|
||||
// 加载基础配置
|
||||
mergeConfigFromFile(config, 'config/_default/site.yml');
|
||||
mergeConfigFromFile(config, 'config/_default/navigation.yml');
|
||||
|
||||
// 加载页面配置
|
||||
if (fs.existsSync('config/_default/pages')) {
|
||||
loadPageConfigs(config, 'config/_default/pages');
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 次高优先级: config.user.yml (传统用户配置)
|
||||
if (fs.existsSync('config.user.yml')) {
|
||||
const userConfigFile = fs.readFileSync('config.user.yml', 'utf8');
|
||||
const userConfig = yaml.load(userConfigFile);
|
||||
|
||||
// 深度合并配置
|
||||
deepMerge(config, userConfig);
|
||||
console.log('Merged legacy user configuration from config.user.yml');
|
||||
}
|
||||
|
||||
// 1. 最高优先级: config/user/ 目录
|
||||
if (fs.existsSync('config/user')) {
|
||||
console.log('Loading modular user configuration from config/user/ (highest priority)');
|
||||
|
||||
// 覆盖基础配置
|
||||
mergeConfigFromFile(config, 'config/user/site.yml');
|
||||
mergeConfigFromFile(config, 'config/user/navigation.yml');
|
||||
|
||||
// 覆盖页面配置
|
||||
if (fs.existsSync('config/user/pages')) {
|
||||
loadPageConfigs(config, 'config/user/pages');
|
||||
}
|
||||
}
|
||||
|
||||
// 处理书签文件(保持现有功能)
|
||||
try {
|
||||
let bookmarksConfig = null;
|
||||
let bookmarksSource = null;
|
||||
|
||||
// 优先尝试读取用户书签配置
|
||||
if (fs.existsSync('bookmarks.user.yml')) {
|
||||
// 按照相同的优先级顺序处理书签配置
|
||||
// 1. 模块化用户书签配置 (最高优先级)
|
||||
if (fs.existsSync('config/user/pages/bookmarks.yml')) {
|
||||
const userBookmarksFile = fs.readFileSync('config/user/pages/bookmarks.yml', 'utf8');
|
||||
bookmarksConfig = yaml.load(userBookmarksFile);
|
||||
bookmarksSource = 'config/user/pages/bookmarks.yml';
|
||||
}
|
||||
// 2. 传统用户书签配置
|
||||
else if (fs.existsSync('bookmarks.user.yml')) {
|
||||
const userBookmarksFile = fs.readFileSync('bookmarks.user.yml', 'utf8');
|
||||
bookmarksConfig = yaml.load(userBookmarksFile);
|
||||
console.log('Using user bookmarks configuration from bookmarks.user.yml');
|
||||
bookmarksSource = 'bookmarks.user.yml';
|
||||
}
|
||||
// 如果没有用户书签配置,则尝试读取默认书签配置
|
||||
// 3. 模块化默认书签配置
|
||||
else if (fs.existsSync('config/_default/pages/bookmarks.yml')) {
|
||||
const defaultBookmarksFile = fs.readFileSync('config/_default/pages/bookmarks.yml', 'utf8');
|
||||
bookmarksConfig = yaml.load(defaultBookmarksFile);
|
||||
bookmarksSource = 'config/_default/pages/bookmarks.yml';
|
||||
}
|
||||
// 4. 传统默认书签配置 (最低优先级)
|
||||
else if (fs.existsSync('bookmarks.yml')) {
|
||||
const bookmarksFile = fs.readFileSync('bookmarks.yml', 'utf8');
|
||||
bookmarksConfig = yaml.load(bookmarksFile);
|
||||
console.log('Using default bookmarks configuration from bookmarks.yml');
|
||||
bookmarksSource = 'bookmarks.yml';
|
||||
}
|
||||
|
||||
// 添加书签页面配置
|
||||
if (bookmarksConfig) {
|
||||
config.bookmarks = bookmarksConfig;
|
||||
console.log(`Using bookmarks configuration from ${bookmarksSource}`);
|
||||
|
||||
// 确保导航中有书签页面
|
||||
const hasBookmarksNav = config.navigation.some(nav => nav.id === 'bookmarks');
|
||||
|
||||
Reference in New Issue
Block a user