hifun-tools 1.3.23 → 1.3.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -70,7 +70,7 @@ class InitCls {
70
70
  }
71
71
  // 默认租户匹配
72
72
  if (host.includes("iggame") || host.includes("localhost")) {
73
- console.info(`🏠 iggame匹配到默认租户`);
73
+ console.info(`🏠 iggame匹配到默认租户2`);
74
74
  return { tenant: "iggame" };
75
75
  }
76
76
  throw new Error("未找到匹配租户");
@@ -80,8 +80,9 @@ class InitCls {
80
80
  const host = location.host;
81
81
  if (host.includes("iggame") ||
82
82
  host.includes("localhost") ||
83
- location.origin.includes(this.localPath.replace(/\/+$/, ""))) {
84
- console.info(`🏠 iggame匹配到默认租户`);
83
+ (!!this.localPath &&
84
+ location.origin.includes(this.localPath.replace(/\/+$/, "")))) {
85
+ console.info(`🏠 iggame匹配到默认租户1`);
85
86
  return { tenant: "iggame" };
86
87
  }
87
88
  throw new Error("无法获取有效的租户信息");
@@ -133,9 +134,9 @@ class InitCls {
133
134
  const response = await fetch(`/lineAddress.txt?t=${Date.now()}`);
134
135
  const configText = await response.text();
135
136
  let baseUrl = JSON.parse(AesDecrypt(configText));
136
- const { lineGroup, tenant } = this.getTenantDict();
137
+ const { lineGroup } = this.getTenantDict();
137
138
  const dictList = this.getTenantDictList();
138
- baseUrl = filterSmartLines(dictList, baseUrl, lineGroup, tenant);
139
+ baseUrl = filterSmartLines(dictList, baseUrl, lineGroup);
139
140
  if (Array.isArray(baseUrl)) {
140
141
  try {
141
142
  this.domainBaseUrl = toStandardUrl(await getOptimalDecodedString(baseUrl));
@@ -153,10 +154,12 @@ class InitCls {
153
154
  return this.domainBaseUrl;
154
155
  }
155
156
  catch (error) {
157
+ console.error(error);
156
158
  if ((this.defaultBaseUrl &&
157
159
  (location.host.includes("iggame") ||
158
160
  location.host.includes("localhost"))) ||
159
- location.origin.includes(this.localPath.replace(/\/+$/, ""))) {
161
+ (!!this.localPath &&
162
+ location.origin.includes(this.localPath.replace(/\/+$/, "")))) {
160
163
  console.info(`🏠 iggame匹配到默认链接`, this.defaultBaseUrl);
161
164
  this.domainBaseUrl = toStandardUrl(this.defaultBaseUrl);
162
165
  return this.domainBaseUrl;
@@ -8,14 +8,5 @@ export declare function isIPv4(str: string): boolean;
8
8
  export declare function getOptimalDecodedString(encodedArray: string[]): Promise<string>;
9
9
  export declare function isDomainMatch(list: string[], target: string): boolean;
10
10
  export declare function toStandardUrl(input: string): string;
11
- /**
12
- * 匹配规则:模糊 + 正则 + 不区分大小写
13
- */
14
11
  export declare function matchBrowser(checkItem: string, currentBrowser: string): boolean;
15
- /**
16
- * 1. 过滤 browserCheck
17
- * 2. 按 tenant 过滤
18
- * 3. 按 groupType(可为空)过滤
19
- * 4. 与 list2 求交集
20
- */
21
12
  export declare function filterSmartLines(list1: TenantDict[], list2: string[], groupType?: string, tenant?: string): string[];
@@ -18,7 +18,6 @@ export async function getOptimalDecodedString(encodedArray) {
18
18
  throw new Error("输入数组为空或无效");
19
19
  const hostname = window.location.hostname;
20
20
  const isIp = isIPv4(hostname);
21
- // ✨ 关键增强:先 trim 再过滤
22
21
  const decodedList = encodedArray
23
22
  .filter(Boolean)
24
23
  .map((v) => v.trim());
@@ -30,7 +29,6 @@ export async function getOptimalDecodedString(encodedArray) {
30
29
  return;
31
30
  }
32
31
  const currentProtocol = window.location.protocol;
33
- // 过滤协议
34
32
  const filteredArr = arr.filter((url) => url.startsWith("http") ? url.startsWith(currentProtocol) : true);
35
33
  const targetArr = filteredArr.length ? filteredArr : arr;
36
34
  if (targetArr.length === 1)
@@ -61,37 +59,33 @@ export async function getOptimalDecodedString(encodedArray) {
61
59
  });
62
60
  return isIp ? await getOptimal(ipList) : await getOptimal(domainList);
63
61
  }
62
+ /**
63
+ * normalizeHost:保留端口,只清理协议
64
+ */
64
65
  function normalizeHost(hostname) {
65
66
  hostname = hostname.trim().toLowerCase();
66
- // 去掉典型协议
67
- if (hostname.startsWith("http://") || hostname.startsWith("https://")) {
68
- try {
69
- hostname = new URL(hostname).hostname;
70
- }
71
- catch (_) { }
67
+ // 如果没有协议,加上 http:// 方便 URL 解析
68
+ let urlStr = hostname;
69
+ if (!/^https?:\/\//i.test(hostname)) {
70
+ urlStr = "http://" + hostname;
71
+ }
72
+ try {
73
+ const url = new URL(urlStr);
74
+ // 保留 hostname + port
75
+ return url.port ? `${url.hostname}:${url.port}` : url.hostname;
76
+ }
77
+ catch (_) {
78
+ return hostname; // 保留原始字符串
72
79
  }
73
- return hostname;
74
80
  }
75
81
  /**
76
- * 域名是否严格匹配,允许 www 特例
77
- *
78
- * 允许:
79
- * www.a.com <=> a.com
80
- * 完全相同
81
- *
82
- * 不允许:
83
- * 1.a.com vs 2.a.com
84
- * 1.a.com vs a.com
85
- * 2.a.com vs a.com
86
- * 1.a.com vs www.a.com
82
+ * 域名严格匹配,允许 www 特例
87
83
  */
88
84
  function isDomainStrictEqual(a, b) {
89
85
  a = normalizeHost(a);
90
86
  b = normalizeHost(b);
91
87
  if (a === b)
92
88
  return true;
93
- // www 特例:只允许这种
94
- // www.x.com <-> x.com
95
89
  const stripWww = (h) => (h.startsWith("www.") ? h.slice(4) : h);
96
90
  return stripWww(a) === stripWww(b);
97
91
  }
@@ -108,26 +102,28 @@ export function toStandardUrl(input) {
108
102
  return "";
109
103
  input = input.trim();
110
104
  let protocol = window?.location?.protocol || "https:";
111
- // 如果没有 http / https,则自动补协议
112
105
  if (!/^https?:\/\//i.test(input)) {
113
106
  input = protocol + "//" + input;
114
107
  }
115
108
  const url = new URL(input);
116
109
  const hostname = url.hostname;
117
- // hostname 必须包含至少 1 个点 或是合法 IPv4,否则判断为无效
118
- const isHostnameValid = /^[a-zA-Z0-9.-]+$/.test(hostname) &&
119
- (hostname.includes(".") || isIPv4(hostname));
110
+ const port = url.port;
111
+ const isHostnameValid = hostname === "localhost" ||
112
+ (/^[a-zA-Z0-9.-]+$/.test(hostname) &&
113
+ (hostname.includes(".") || isIPv4(hostname)));
120
114
  if (!isHostnameValid) {
121
115
  return "";
122
116
  }
123
- return `${url.protocol}//${hostname}`;
117
+ return port
118
+ ? `${url.protocol}//${hostname}:${port}`
119
+ : `${url.protocol}//${hostname}`;
124
120
  }
125
121
  catch (e) {
126
122
  return "";
127
123
  }
128
124
  }
129
125
  /**
130
- * 浏览器识别:返回一个归一化的浏览器类型字符串
126
+ * 浏览器识别
131
127
  */
132
128
  function detectBrowser() {
133
129
  const ua = navigator.userAgent.toLowerCase();
@@ -160,17 +156,11 @@ function detectBrowser() {
160
156
  }
161
157
  return "unknown";
162
158
  }
163
- /**
164
- * 匹配规则:模糊 + 正则 + 不区分大小写
165
- */
166
159
  export function matchBrowser(checkItem, currentBrowser) {
167
- if (!checkItem)
168
- return false;
169
- if (!currentBrowser)
160
+ if (!checkItem || !currentBrowser)
170
161
  return false;
171
162
  const normalized = checkItem.toString().toLowerCase();
172
163
  const browser = currentBrowser.toLowerCase();
173
- // 正则格式,如 "/uc/i"
174
164
  if (normalized.startsWith("/") && normalized.endsWith("/")) {
175
165
  try {
176
166
  const body = normalized.slice(1, -1);
@@ -179,15 +169,8 @@ export function matchBrowser(checkItem, currentBrowser) {
179
169
  }
180
170
  catch (_) { }
181
171
  }
182
- // 字符串模糊匹配
183
172
  return browser.includes(normalized);
184
173
  }
185
- /**
186
- * 1. 过滤 browserCheck
187
- * 2. 按 tenant 过滤
188
- * 3. 按 groupType(可为空)过滤
189
- * 4. 与 list2 求交集
190
- */
191
174
  export function filterSmartLines(list1, list2, groupType, tenant) {
192
175
  if (!Array.isArray(list1) || !Array.isArray(list2)) {
193
176
  throw new Error("前两个参数必须是数组");
@@ -198,13 +181,10 @@ export function filterSmartLines(list1, list2, groupType, tenant) {
198
181
  const blocked = checks.some((checkItem) => matchBrowser(checkItem, currentBrowser));
199
182
  return !blocked;
200
183
  });
201
- if (tenant) {
184
+ if (tenant)
202
185
  result = result.filter((item) => item.tenant === tenant);
203
- }
204
- if (groupType) {
186
+ if (groupType)
205
187
  result = result.filter((item) => item.lineGroup === groupType);
206
- }
207
- console.log("list2.map(toStandardUrl)", list2.map(toStandardUrl), list2);
208
188
  const lines = result.map((item) => toStandardUrl(item.line));
209
- return list2.map(toStandardUrl).filter((v) => isDomainMatch(lines, v)); // ✨ 使用域名匹配
189
+ return list2.map(toStandardUrl).filter((v) => isDomainMatch(lines, v));
210
190
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hifun-tools",
3
- "version": "1.3.23",
3
+ "version": "1.3.25",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",