@nsnanocat/util 1.8.10 → 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 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
- Store.Settings = { ...Store.Settings, ...database?.[name]?.Settings };
23
- Store.Configs = { ...Store.Configs, ...database?.[name]?.Configs };
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": "exit 0"
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.8.10"
36
+ "version": "1.9.2"
36
37
  }
@@ -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));