-
Notifications
You must be signed in to change notification settings - Fork 283
Expand file tree
/
Copy pathsites-map.js
More file actions
136 lines (119 loc) · 4.46 KB
/
sites-map.js
File metadata and controls
136 lines (119 loc) · 4.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
* 站点映射工具模块
* 提供查询字符串解析和站点映射配置读取功能
* @module sites-map
*/
import path from "path";
import {existsSync, readFileSync} from "fs";
import {fileURLToPath} from "url";
import {createHash} from "crypto";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const _config_path = path.join(__dirname, '../config'); // 配置文件路径
// 缓存相关变量
const sitesMapCache = new Map(); // 缓存映射:configDir -> {hash, data}
/**
* 计算字符串的MD5哈希值
* @param {string} content - 要计算哈希的字符串内容
* @returns {string} MD5哈希值
*/
function getContentHash(content) {
return createHash('md5').update(content, 'utf8').digest('hex');
}
/**
* 清除站点映射缓存
* @param {string} configDir - 可选,指定要清除的配置目录缓存,不传则清除所有缓存
*/
function clearSitesMapCache(configDir = null) {
if (configDir) {
sitesMapCache.delete(configDir);
} else {
sitesMapCache.clear();
}
}
/**
* 将查询字符串解析为对象
* @param {string} query - URL查询字符串
* @returns {Object} 解析后的查询对象
* @example
* getQueryObj("name=test&id=123") // returns {name: "test", id: "123"}
*/
function getQueryObj(query) {
// 使用 URLSearchParams 解析查询字符串
const searchParams = new URLSearchParams(query);
// 创建空的查询对象
const queryObject = {};
// 遍历所有查询参数并添加到对象中
for (const [key, value] of searchParams.entries()) {
queryObject[key] = value;
}
return queryObject
}
/**
* 读取并解析站点映射配置文件(带缓存优化)
* @param {string} configDir - 配置文件目录路径
* @returns {Object} 站点映射对象,键为站点名,值为配置数组
* @description
* 配置文件格式:站点名@@查询字符串@@别名(可选)
* 每行一个配置,支持同一站点多个配置
*/
function getSitesMap(configDir = _config_path) {
// 初始化站点映射对象
let SitesMap = {};
// 构建配置文件路径
let SitesMapPath = path.join(configDir, './map.txt');
// 定义分隔符
let splitStr = '@@';
// 检查配置文件是否存在
if (existsSync(SitesMapPath)) {
try {
// 读取配置文件内容
let SitesMapText = readFileSync(SitesMapPath, 'utf-8');
// 计算文件内容的hash值
const contentHash = getContentHash(SitesMapText);
// 检查缓存
const cacheKey = configDir;
const cachedData = sitesMapCache.get(cacheKey);
if (cachedData && cachedData.hash === contentHash) {
// 缓存命中,直接返回缓存的数据
return cachedData.data;
}
// 缓存未命中或内容已变更,重新解析
// 按行分割并过滤空行
let SitesMapLines = SitesMapText.split('\n').filter(it => it);
// 遍历每一行配置
SitesMapLines.forEach((line) => {
// 解析站点名(第一部分)
let SitesMapKey = line.split(splitStr)[0].trim();
// 如果站点名不存在,初始化为空数组
if (!SitesMap.hasOwnProperty(SitesMapKey)) {
SitesMap[SitesMapKey] = [];
}
// 解析查询字符串(第二部分)
let SitesMapQuery = line.split(splitStr)[1].trim();
// 解析别名(第三部分,可选,默认为站点名)
let SitesMapAlias = line.split(splitStr).length > 2 ? line.split(splitStr)[2].trim() : SitesMapKey;
// 添加配置到站点映射中
SitesMap[SitesMapKey].push({
alias: SitesMapAlias, // 站点别名
queryStr: SitesMapQuery, // 原始查询字符串
queryObject: getQueryObj(SitesMapQuery), // 解析后的查询对象
});
});
// 更新缓存
sitesMapCache.set(cacheKey, {
hash: contentHash,
data: SitesMap
});
return SitesMap
} catch (e) {
// 读取或解析失败时静默处理,返回空映射
}
}
// 文件不存在或处理失败时返回空映射
return SitesMap
}
export {
getQueryObj,
getSitesMap,
clearSitesMapCache
};