@nsnanocat/util 1.8.9 → 1.9.2
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/getStorage.mjs +2 -2
- package/package.json +3 -2
- package/polyfill/Lodash.mjs +86 -0
- package/polyfill/fetch.mjs +1 -0
package/getStorage.mjs
CHANGED
|
@@ -19,8 +19,8 @@ export function getStorage(key, names, database) {
|
|
|
19
19
|
//Console.debug("Default", `Store.Settings类型: ${typeof Store.Settings}`, `Store.Settings: ${JSON.stringify(Store.Settings)}`);
|
|
20
20
|
/***************** Database *****************/
|
|
21
21
|
names.forEach(name => {
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
_.merge(Store.Settings, database?.[name]?.Settings);
|
|
23
|
+
_.merge(Store.Configs, database?.[name]?.Configs);
|
|
24
24
|
});
|
|
25
25
|
//Console.debug("Database", `Store.Settings类型: ${typeof Store.Settings}`, `Store.Settings: ${JSON.stringify(Store.Settings)}`);
|
|
26
26
|
/***************** Argument *****************/
|
package/package.json
CHANGED
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"type": "module",
|
|
18
18
|
"scripts": {
|
|
19
19
|
"tsc:build": "npx tsc",
|
|
20
|
-
"test": "
|
|
20
|
+
"test": "node --test test/*.test.js",
|
|
21
|
+
"test:merge": "node --test test/Lodash.merge.test.js"
|
|
21
22
|
},
|
|
22
23
|
"repository": {
|
|
23
24
|
"type": "git",
|
|
@@ -32,5 +33,5 @@
|
|
|
32
33
|
"devDependencies": {
|
|
33
34
|
"typescript": "^5.6.3"
|
|
34
35
|
},
|
|
35
|
-
"version": "1.
|
|
36
|
+
"version": "1.9.2"
|
|
36
37
|
}
|
package/polyfill/Lodash.mjs
CHANGED
|
@@ -22,6 +22,92 @@ export class Lodash {
|
|
|
22
22
|
return result === undefined ? defaultValue : result;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* 递归合并源对象的自身可枚举属性到目标对象
|
|
27
|
+
* @description 简化版 lodash.merge,用于合并配置对象
|
|
28
|
+
*
|
|
29
|
+
* 适用情况:
|
|
30
|
+
* - 合并嵌套的配置/设置对象
|
|
31
|
+
* - 需要深度合并而非浅层覆盖的场景
|
|
32
|
+
* - 多个源对象依次合并到目标对象
|
|
33
|
+
*
|
|
34
|
+
* 限制:
|
|
35
|
+
* - 仅处理普通对象 (Plain Object),不处理 Date/RegExp 等特殊对象
|
|
36
|
+
* - Map/Set 仅支持同类型合并,不递归内部值
|
|
37
|
+
* - 数组会被直接覆盖,不会合并数组元素
|
|
38
|
+
* - 不处理循环引用,可能导致栈溢出
|
|
39
|
+
* - 不复制 Symbol 属性和不可枚举属性
|
|
40
|
+
* - 不保留原型链,仅处理自身属性
|
|
41
|
+
* - 会修改原始目标对象 (mutates target)
|
|
42
|
+
*
|
|
43
|
+
* @param {object} object - 目标对象
|
|
44
|
+
* @param {...object} sources - 源对象(可多个)
|
|
45
|
+
* @returns {object} 返回合并后的目标对象
|
|
46
|
+
* @example
|
|
47
|
+
* const target = { a: { b: 1 }, c: 2 };
|
|
48
|
+
* const source = { a: { d: 3 }, e: 4 };
|
|
49
|
+
* Lodash.merge(target, source);
|
|
50
|
+
* // => { a: { b: 1, d: 3 }, c: 2, e: 4 }
|
|
51
|
+
*/
|
|
52
|
+
static merge(object, ...sources) {
|
|
53
|
+
if (object === null || object === undefined) return object;
|
|
54
|
+
|
|
55
|
+
for (const source of sources) {
|
|
56
|
+
if (source === null || source === undefined) continue;
|
|
57
|
+
|
|
58
|
+
for (const key of Object.keys(source)) {
|
|
59
|
+
const sourceValue = source[key];
|
|
60
|
+
const targetValue = object[key];
|
|
61
|
+
|
|
62
|
+
switch (true) {
|
|
63
|
+
case Lodash.#isPlainObject(sourceValue) && Lodash.#isPlainObject(targetValue):
|
|
64
|
+
// 递归合并对象
|
|
65
|
+
object[key] = Lodash.merge(targetValue, sourceValue);
|
|
66
|
+
break;
|
|
67
|
+
case sourceValue instanceof Map && targetValue instanceof Map:
|
|
68
|
+
// 合并 Map(空 Map 跳过)
|
|
69
|
+
if (sourceValue.size > 0) {
|
|
70
|
+
for (const [k, v] of sourceValue) {
|
|
71
|
+
targetValue.set(k, v);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
break;
|
|
75
|
+
case sourceValue instanceof Set && targetValue instanceof Set:
|
|
76
|
+
// 合并 Set(空 Set 跳过)
|
|
77
|
+
if (sourceValue.size > 0) {
|
|
78
|
+
for (const v of sourceValue) {
|
|
79
|
+
targetValue.add(v);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
case Array.isArray(sourceValue) && sourceValue.length === 0 && targetValue !== undefined:
|
|
84
|
+
// 空数组不覆盖已有值
|
|
85
|
+
break;
|
|
86
|
+
case (sourceValue instanceof Map && sourceValue.size === 0 && targetValue !== undefined):
|
|
87
|
+
case (sourceValue instanceof Set && sourceValue.size === 0 && targetValue !== undefined):
|
|
88
|
+
// 空 Map/Set 不覆盖已有值
|
|
89
|
+
break;
|
|
90
|
+
case sourceValue !== undefined:
|
|
91
|
+
object[key] = sourceValue;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return object;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* 判断值是否为普通对象 (Plain Object)
|
|
102
|
+
* @param {*} value - 要检查的值
|
|
103
|
+
* @returns {boolean} 如果是普通对象返回 true
|
|
104
|
+
*/
|
|
105
|
+
static #isPlainObject(value) {
|
|
106
|
+
if (value === null || typeof value !== "object") return false;
|
|
107
|
+
const proto = Object.getPrototypeOf(value);
|
|
108
|
+
return proto === null || proto === Object.prototype;
|
|
109
|
+
}
|
|
110
|
+
|
|
25
111
|
static omit(object = {}, paths = []) {
|
|
26
112
|
if (!Array.isArray(paths)) paths = [paths.toString()];
|
|
27
113
|
paths.forEach(path => Lodash.unset(object, path));
|
package/polyfill/fetch.mjs
CHANGED
|
@@ -116,6 +116,7 @@ export async function fetch(resource, options = {}) {
|
|
|
116
116
|
});
|
|
117
117
|
case "Quantumult X":
|
|
118
118
|
// 转换请求参数
|
|
119
|
+
resource.timeout = resource.timeout * 1000;
|
|
119
120
|
if (resource.policy) _.set(resource, "opts.policy", resource.policy);
|
|
120
121
|
if (typeof resource["auto-redirect"] === "boolean") _.set(resource, "opts.redirection", resource["auto-redirect"]);
|
|
121
122
|
// 转换请求体
|