hifun-tools 1.3.23 → 1.3.24
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.
- package/dist/init/getResource.d.ts +1 -1
- package/dist/init/getResource.js +34 -12
- package/dist/init/index.js +7 -4
- package/dist/init/utils.d.ts +0 -9
- package/dist/init/utils.js +28 -48
- package/package.json +1 -1
package/dist/init/getResource.js
CHANGED
|
@@ -1,15 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 通用资源加载函数(支持 Vite
|
|
2
|
+
* 通用资源加载函数(支持 Vite / Webpack / Rspack)
|
|
3
3
|
* @param path - 相对路径,如 "tenant/config.json" 或 "tenant/logo.png"
|
|
4
4
|
*/
|
|
5
5
|
export function getResource(path) {
|
|
6
6
|
const isVite = typeof import.meta !== "undefined" && !!import.meta.env;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
// ---------------- 新增 RSPACK 检测 ----------------
|
|
8
|
+
const isRspack = typeof __rspack_require__ === "function" ||
|
|
9
|
+
(typeof __webpack_require__ === "function" &&
|
|
10
|
+
!!__webpack_require__.s && // Rspack 专属字段
|
|
11
|
+
!__webpack_require__.m); // Webpack 有 m,Rspack 不一定有
|
|
12
|
+
const isWebpack = !isRspack && // 不冲突:优先识别 Rspack
|
|
13
|
+
(typeof __webpack_require__ === "function" ||
|
|
14
|
+
(typeof require !== "undefined" &&
|
|
15
|
+
typeof require.context === "function"));
|
|
16
|
+
// ---------------- RSPACK ----------------
|
|
17
|
+
if (isRspack) {
|
|
18
|
+
try {
|
|
19
|
+
const ctx = require.context("/config", true, /\.(json|png|jpg|jpeg|svg|webp)$/);
|
|
20
|
+
const files = ctx.keys();
|
|
21
|
+
const match = files.find((key) => key.endsWith(path));
|
|
22
|
+
if (!match) {
|
|
23
|
+
console.warn(`[getResource] 未找到文件: ${path}`);
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return ctx(match);
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
console.error("[getResource] Rspack context 加载失败", e);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// ---------------- VITE ----------------
|
|
33
|
+
else if (isVite) {
|
|
34
|
+
const { glob } = import.meta;
|
|
35
|
+
const modules = glob([
|
|
13
36
|
"/config/**/*.json",
|
|
14
37
|
"/config/**/*.png",
|
|
15
38
|
"/config/**/*.jpg",
|
|
@@ -25,11 +48,10 @@ export function getResource(path) {
|
|
|
25
48
|
console.warn(`[getResource] 未找到文件: ${path}`);
|
|
26
49
|
return null;
|
|
27
50
|
}
|
|
28
|
-
|
|
29
|
-
return mod;
|
|
51
|
+
return match[1];
|
|
30
52
|
}
|
|
31
|
-
|
|
32
|
-
|
|
53
|
+
// ---------------- WEBPACK ----------------
|
|
54
|
+
else if (isWebpack) {
|
|
33
55
|
const ctx = require.context("/config", true, /\.(json|png|jpg|jpeg|svg|webp)$/);
|
|
34
56
|
const files = ctx.keys();
|
|
35
57
|
const match = files.find((key) => key.endsWith(path));
|
|
@@ -39,6 +61,6 @@ export function getResource(path) {
|
|
|
39
61
|
}
|
|
40
62
|
return ctx(match);
|
|
41
63
|
}
|
|
42
|
-
console.error("[getResource] 不支持的构建环境(需要 Vite
|
|
64
|
+
console.error("[getResource] 不支持的构建环境(需要 Vite/Webpack/Rspack)");
|
|
43
65
|
return null;
|
|
44
66
|
}
|
package/dist/init/index.js
CHANGED
|
@@ -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
|
-
|
|
84
|
-
|
|
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("无法获取有效的租户信息");
|
|
@@ -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
|
-
|
|
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;
|
package/dist/init/utils.d.ts
CHANGED
|
@@ -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[];
|
package/dist/init/utils.js
CHANGED
|
@@ -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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
118
|
-
const isHostnameValid =
|
|
119
|
-
(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
|
|
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
|
}
|