@nsnanocat/util 2.1.0 → 2.1.1

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/lib/app.mjs CHANGED
@@ -1,7 +1,18 @@
1
1
  /**
2
- * Current app name
2
+ * 当前运行平台名称。
3
+ * Current runtime platform name.
3
4
  *
4
- * @type {("Quantumult X" | "Loon" | "Shadowrocket" | "Node.js" | "Egern" | "Surge" | "Stash")}
5
+ * 识别顺序:
6
+ * Detection order:
7
+ * 1) `$task` -> Quantumult X
8
+ * 2) `$loon` -> Loon
9
+ * 3) `$rocket` -> Shadowrocket
10
+ * 4) `module` -> Node.js
11
+ * 5) `Egern` -> Egern
12
+ * 6) `$environment["surge-version"]` -> Surge
13
+ * 7) `$environment["stash-version"]` -> Stash
14
+ *
15
+ * @type {("Quantumult X" | "Loon" | "Shadowrocket" | "Node.js" | "Egern" | "Surge" | "Stash" | undefined)}
5
16
  */
6
17
  export const $app = (() => {
7
18
  const keys = Object.keys(globalThis);
package/lib/argument.mjs CHANGED
@@ -1,6 +1,24 @@
1
1
  import { Console } from "../polyfill/Console.mjs";
2
2
  import { Lodash as _ } from "../polyfill/Lodash.mjs";
3
3
 
4
+ /**
5
+ * 统一 `$argument` 输入格式并展开深路径。
6
+ * Normalize `$argument` input format and expand deep paths.
7
+ *
8
+ * 平台差异:
9
+ * Platform differences:
10
+ * - Surge / Stash / Egern 常见为字符串参数: `a=1&b=2`
11
+ * - Surge / Stash / Egern usually pass string args: `a=1&b=2`
12
+ * - Loon 支持字符串和对象两种形态
13
+ * - Loon supports both string and object forms
14
+ * - Quantumult X / Shadowrocket 一般不提供 `$argument`
15
+ * - Quantumult X / Shadowrocket usually do not expose `$argument`
16
+ *
17
+ * 执行时机:
18
+ * Execution timing:
19
+ * - 该模块为即时执行模块,`import` 时立即处理全局 `$argument`
20
+ * - This module executes immediately and mutates global `$argument` on import
21
+ */
4
22
  (() => {
5
23
  Console.debug("☑️ $argument");
6
24
  switch (typeof $argument) {
package/lib/done.mjs CHANGED
@@ -4,10 +4,30 @@ import { Lodash as _ } from "../polyfill/Lodash.mjs";
4
4
  import { StatusTexts } from "../polyfill/StatusTexts.mjs";
5
5
 
6
6
  /**
7
- * Complete the script execution
7
+ * `done` 的统一入参结构。
8
+ * Unified `done` input payload.
8
9
  *
9
- * @export
10
- * @param {object} object
10
+ * @typedef {object} DonePayload
11
+ * @property {number|string} [status] 响应状态码或状态行 / Response status code or status line.
12
+ * @property {string} [url] 响应 URL / Response URL.
13
+ * @property {Record<string, any>} [headers] 响应头 / Response headers.
14
+ * @property {string|ArrayBuffer|ArrayBufferView} [body] 响应体 / Response body.
15
+ * @property {ArrayBuffer} [bodyBytes] 二进制响应体 / Binary response body.
16
+ * @property {string} [policy] 指定策略名 / Preferred policy name.
17
+ */
18
+
19
+ /**
20
+ * 结束脚本执行并按平台转换参数。
21
+ * Complete script execution with platform-specific parameter mapping.
22
+ *
23
+ * 说明:
24
+ * Notes:
25
+ * - 这是调用入口,平台原生 `$done` 差异在内部处理
26
+ * - This is the call entry and native `$done` differences are handled internally
27
+ * - Node.js 不调用 `$done`,而是直接退出进程
28
+ * - Node.js does not call `$done`; it exits the process directly
29
+ *
30
+ * @param {DonePayload} [object={}] 统一响应对象 / Unified response object.
11
31
  * @returns {void}
12
32
  */
13
33
  export function done(object = {}) {
@@ -1,6 +1,28 @@
1
1
  import { $app } from "./app.mjs";
2
2
 
3
+ /**
4
+ * 标准化后的运行环境对象。
5
+ * Normalized runtime environment object.
6
+ *
7
+ * - Surge/Stash/Egern: 基于全局 `$environment` 并补充 `app`
8
+ * - Surge/Stash/Egern: based on global `$environment` with `app` patched
9
+ * - Loon: 解析 `$loon` 得到设备与版本信息
10
+ * - Loon: parse `$loon` into device/version fields
11
+ * - Quantumult X: 仅返回 `{ app: "Quantumult X" }`
12
+ * - Quantumult X: returns `{ app: "Quantumult X" }` only
13
+ * - Node.js: 复用 `process.env` 并写入 `process.env.app`
14
+ * - Node.js: reuses `process.env` and writes `process.env.app`
15
+ *
16
+ * @type {Record<string, any>}
17
+ */
3
18
  export const $environment = environment();
19
+
20
+ /**
21
+ * 获取标准化环境对象。
22
+ * Build and return the normalized environment object.
23
+ *
24
+ * @returns {Record<string, any>}
25
+ */
4
26
  export function environment() {
5
27
  switch ($app) {
6
28
  case "Surge":
package/lib/index.js CHANGED
@@ -4,3 +4,15 @@ export * from "./done.mjs";
4
4
  export * from "./notification.mjs";
5
5
  export * from "./time.mjs";
6
6
  export * from "./wait.mjs";
7
+
8
+ /**
9
+ * 已标准化的 `$argument` 快照。
10
+ * Normalized `$argument` snapshot.
11
+ */
12
+ export const $argument = globalThis.$argument ?? {};
13
+
14
+ /**
15
+ * 兼容别名(建议优先使用 `$argument`)。
16
+ * Backward-compatible alias (prefer `$argument`).
17
+ */
18
+ export const argument = $argument;
@@ -2,20 +2,41 @@ import { $app } from "./app.mjs";
2
2
  import { Console } from "../polyfill/Console.mjs";
3
3
 
4
4
  /**
5
- * 系统通知
5
+ * 通知内容扩展参数。
6
+ * Extended notification content options.
6
7
  *
7
- * > 通知参数: 同时支持 QuanX 和 Loon 两种格式, EnvJs根据运行环境自动转换, Surge 环境不支持多媒体通知
8
- *
9
- * 示例:
10
- * $.msg(title, subtitle, body, "twitter://")
11
- * $.msg(title, subtitle, body, { "open-url": "twitter://", "media-url": "https://github.githubassets.com/images/modules/open_graph/github-mark.png" })
12
- * $.msg(title, subtitle, body, { "open-url": "https://bing.com", "media-url": "https://github.githubassets.com/images/modules/open_graph/github-mark.png" })
8
+ * @typedef {object|string|number|boolean} NotificationContent
9
+ * @property {string} [open] 打开链接 / Open URL.
10
+ * @property {string} ["open-url"] 打开链接 (QuanX) / Open URL (QuanX).
11
+ * @property {string} [url] 打开链接 / Open URL.
12
+ * @property {string} [openUrl] 打开链接 (Loon/Shadowrocket) / Open URL (Loon/Shadowrocket).
13
+ * @property {string} [copy] 复制文本 / Copy text.
14
+ * @property {string} ["update-pasteboard"] 复制文本 (QuanX) / Copy text (QuanX).
15
+ * @property {string} [updatePasteboard] 复制文本 / Copy text.
16
+ * @property {string} [media] 媒体 URL 或 Base64 / Media URL or Base64.
17
+ * @property {string} ["media-url"] 媒体 URL / Media URL.
18
+ * @property {string} [mediaUrl] 媒体 URL / Media URL.
19
+ * @property {string} [mime] Base64 媒体 MIME / MIME type for Base64 media.
20
+ * @property {number} ["auto-dismiss"] 自动消失秒数 / Auto dismiss seconds.
21
+ * @property {string} [sound] 提示音 / Notification sound.
22
+ */
23
+
24
+ /**
25
+ * 发送系统通知并按平台适配参数格式。
26
+ * Send system notification with platform-specific payload mapping.
13
27
  *
14
- * @param {string} title 标题
15
- * @param {string} subtitle 副标题
16
- * @param {string} body 内容
17
- * @param {*} mutableContent 通知扩展字段
28
+ * 说明:
29
+ * Notes:
30
+ * - iOS App 平台调用 `$notification.post` 或 `$notify`
31
+ * - iOS app platforms call `$notification.post` or `$notify`
32
+ * - Node.js 不支持 iOS 通知接口,仅输出日志
33
+ * - Node.js does not support iOS notification APIs; it logs only
18
34
  *
35
+ * @param {string} [title=`ℹ️ ${$app} 通知`] 标题 / Title.
36
+ * @param {string} [subtitle=""] 副标题 / Subtitle.
37
+ * @param {string} [body=""] 内容 / Message body.
38
+ * @param {NotificationContent} [content={}] 扩展参数 / Extended content options.
39
+ * @returns {void}
19
40
  */
20
41
  export function notification(title = `ℹ️ ${$app} 通知`, subtitle = "", body = "", content = {}) {
21
42
  const mutableContent = MutableContent(content);
@@ -39,6 +60,14 @@ export function notification(title = `ℹ️ ${$app} 通知`, subtitle = "", bod
39
60
  Console.groupEnd();
40
61
  }
41
62
 
63
+ /**
64
+ * 将统一通知参数转换为平台可识别字段。
65
+ * Convert normalized content into platform-recognized fields.
66
+ *
67
+ * @private
68
+ * @param {NotificationContent} content 通知扩展参数 / Extended content options.
69
+ * @returns {Record<string, any>}
70
+ */
42
71
  const MutableContent = content => {
43
72
  const mutableContent = {};
44
73
  switch (typeof content) {
package/lib/runScript.mjs CHANGED
@@ -3,6 +3,27 @@ import { fetch } from "../polyfill/fetch.mjs";
3
3
  import { Lodash as _ } from "../polyfill/Lodash.mjs";
4
4
  import { Storage } from "../polyfill/Storage.mjs";
5
5
 
6
+ /**
7
+ * 远程脚本执行选项。
8
+ * Remote script execution options.
9
+ *
10
+ * @typedef {object} RunScriptOptions
11
+ * @property {number} [timeout] 执行超时秒数 / Timeout in seconds.
12
+ */
13
+
14
+ /**
15
+ * 通过 BoxJS HTTP API 触发脚本执行。
16
+ * Trigger script execution through BoxJS HTTP API.
17
+ *
18
+ * 依赖键:
19
+ * Required keys:
20
+ * - `@chavy_boxjs_userCfgs.httpapi` (`password@host:port`)
21
+ * - `@chavy_boxjs_userCfgs.httpapi_timeout`
22
+ *
23
+ * @param {string} script 脚本文本 / Script source text.
24
+ * @param {RunScriptOptions} [runOpts] 运行选项 / Runtime options.
25
+ * @returns {Promise<void>}
26
+ */
6
27
  export async function runScript(script, runOpts) {
7
28
  let httpapi = Storage.getItem("@chavy_boxjs_userCfgs.httpapi");
8
29
  httpapi = httpapi?.replace?.(/\n/g, "")?.trim();
package/lib/time.mjs CHANGED
@@ -1,14 +1,14 @@
1
1
  /**
2
- * time
3
- * 时间格式化
4
- * [version of ISO8601]{@link https://262.ecma-international.org/5.1/#sec-15.9.1.15}
5
- * 示例:time("yyyy-MM-dd qq HH:mm:ss.S") YYYY-MM-DDTHH:mm:ss.sssZ
6
- * :time("yyyyMMddHHmmssS")
7
- * YY:年 MM:月 dd:日 S:季 HH:时 m:分 ss:秒 sss:毫秒 Z:时区
8
- * 其中y可选0-4位占位符、S可选0-1位占位符,其余可选0-2位占位符
9
- * @param {string} format 格式化参数
10
- * @param {number} ts 可选: 根据指定时间戳返回格式化日期
2
+ * 按模板格式化时间字符串。
3
+ * Format date/time into a template string.
11
4
  *
5
+ * 支持占位符:
6
+ * Supported tokens:
7
+ * - `YY`, `yyyy`, `MM`, `dd`, `HH`, `mm`, `ss`, `sss`, `S`
8
+ *
9
+ * @param {string} format 格式模板 / Format template.
10
+ * @param {number} [ts] 可选时间戳 / Optional timestamp.
11
+ * @returns {string}
12
12
  */
13
13
  export function time(format, ts) {
14
14
  const date = ts ? new Date(ts) : new Date();
package/lib/wait.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
- * wait
2
+ * 延时等待指定毫秒后继续执行。
3
+ * Wait for the given milliseconds before continuing.
3
4
  *
4
- * @export
5
- * @param {number} [delay=1000]
6
- * @returns {Promise<resolve>}
5
+ * @param {number} [delay=1000] 延迟毫秒 / Delay in milliseconds.
6
+ * @returns {Promise<void>}
7
7
  */
8
8
  export function wait(delay = 1000) {
9
9
  return new Promise(resolve => setTimeout(resolve, delay));
package/package.json CHANGED
@@ -39,5 +39,5 @@
39
39
  "registry": "https://registry.npmjs.org/",
40
40
  "access": "public"
41
41
  },
42
- "version": "2.1.0"
42
+ "version": "2.1.1"
43
43
  }
@@ -1,12 +1,41 @@
1
1
  import { $app } from "../lib/app.mjs";
2
2
 
3
+ /**
4
+ * 统一日志工具,兼容各脚本平台与 Node.js。
5
+ * Unified logger compatible with script platforms and Node.js.
6
+ *
7
+ * logLevel 用法:
8
+ * logLevel usage:
9
+ * - 可读: `Console.logLevel` 返回 `OFF|ERROR|WARN|INFO|DEBUG|ALL`
10
+ * - Read: `Console.logLevel` returns `OFF|ERROR|WARN|INFO|DEBUG|ALL`
11
+ * - 可写: 数字 `0~5` 或字符串 `off/error/warn/info/debug/all`
12
+ * - Write: number `0~5` or string `off/error/warn/info/debug/all`
13
+ *
14
+ * @example
15
+ * Console.logLevel = "debug";
16
+ * Console.debug("only shown when level >= DEBUG");
17
+ * Console.logLevel = 2; // WARN
18
+ */
3
19
  export class Console {
4
20
  static #counts = new Map([]);
5
21
  static #groups = [];
6
22
  static #times = new Map([]);
7
23
 
24
+ /**
25
+ * 清空控制台(当前为空实现)。
26
+ * Clear console (currently a no-op).
27
+ *
28
+ * @returns {void}
29
+ */
8
30
  static clear = () => {};
9
31
 
32
+ /**
33
+ * 增加计数器并打印当前值。
34
+ * Increment counter and print the current value.
35
+ *
36
+ * @param {string} [label="default"] 计数器名称 / Counter label.
37
+ * @returns {void}
38
+ */
10
39
  static count = (label = "default") => {
11
40
  switch (Console.#counts.has(label)) {
12
41
  case true:
@@ -19,6 +48,13 @@ export class Console {
19
48
  Console.log(`${label}: ${Console.#counts.get(label)}`);
20
49
  };
21
50
 
51
+ /**
52
+ * 重置计数器。
53
+ * Reset a counter.
54
+ *
55
+ * @param {string} [label="default"] 计数器名称 / Counter label.
56
+ * @returns {void}
57
+ */
22
58
  static countReset = (label = "default") => {
23
59
  switch (Console.#counts.has(label)) {
24
60
  case true:
@@ -31,12 +67,26 @@ export class Console {
31
67
  }
32
68
  };
33
69
 
70
+ /**
71
+ * 输出调试日志。
72
+ * Print debug logs.
73
+ *
74
+ * @param {...any} msg 日志内容 / Log messages.
75
+ * @returns {void}
76
+ */
34
77
  static debug = (...msg) => {
35
78
  if (Console.#level < 4) return;
36
79
  msg = msg.map(m => `🅱️ ${m}`);
37
80
  Console.log(...msg);
38
81
  };
39
82
 
83
+ /**
84
+ * 输出错误日志。
85
+ * Print error logs.
86
+ *
87
+ * @param {...any} msg 日志内容 / Log messages.
88
+ * @returns {void}
89
+ */
40
90
  static error(...msg) {
41
91
  if (Console.#level < 1) return;
42
92
  switch ($app) {
@@ -56,12 +106,39 @@ export class Console {
56
106
  Console.log(...msg);
57
107
  }
58
108
 
109
+ /**
110
+ * `error` 的别名。
111
+ * Alias of `error`.
112
+ *
113
+ * @param {...any} msg 日志内容 / Log messages.
114
+ * @returns {void}
115
+ */
59
116
  static exception = (...msg) => Console.error(...msg);
60
117
 
118
+ /**
119
+ * 进入日志分组。
120
+ * Enter a log group.
121
+ *
122
+ * @param {string} label 分组名 / Group label.
123
+ * @returns {number}
124
+ */
61
125
  static group = label => Console.#groups.unshift(label);
62
126
 
127
+ /**
128
+ * 退出日志分组。
129
+ * Exit the latest log group.
130
+ *
131
+ * @returns {*}
132
+ */
63
133
  static groupEnd = () => Console.#groups.shift();
64
134
 
135
+ /**
136
+ * 输出信息日志。
137
+ * Print info logs.
138
+ *
139
+ * @param {...any} msg 日志内容 / Log messages.
140
+ * @returns {void}
141
+ */
65
142
  static info(...msg) {
66
143
  if (Console.#level < 3) return;
67
144
  msg = msg.map(m => `ℹ️ ${m}`);
@@ -70,6 +147,12 @@ export class Console {
70
147
 
71
148
  static #level = 3;
72
149
 
150
+ /**
151
+ * 获取日志级别文本。
152
+ * Get current log level text.
153
+ *
154
+ * @returns {"OFF"|"ERROR"|"WARN"|"INFO"|"DEBUG"|"ALL"}
155
+ */
73
156
  static get logLevel() {
74
157
  switch (Console.#level) {
75
158
  case 0:
@@ -88,6 +171,12 @@ export class Console {
88
171
  }
89
172
  }
90
173
 
174
+ /**
175
+ * 设置日志级别。
176
+ * Set current log level.
177
+ *
178
+ * @param {number|string} level 级别值 / Level value.
179
+ */
91
180
  static set logLevel(level) {
92
181
  switch (typeof level) {
93
182
  case "string":
@@ -130,6 +219,13 @@ export class Console {
130
219
  }
131
220
  }
132
221
 
222
+ /**
223
+ * 输出通用日志。
224
+ * Print generic logs.
225
+ *
226
+ * @param {...any} msg 日志内容 / Log messages.
227
+ * @returns {void}
228
+ */
133
229
  static log = (...msg) => {
134
230
  if (Console.#level === 0) return;
135
231
  msg = msg.map(log => {
@@ -157,16 +253,44 @@ export class Console {
157
253
  console.log(msg.join("\n"));
158
254
  };
159
255
 
256
+ /**
257
+ * 开始计时。
258
+ * Start timer.
259
+ *
260
+ * @param {string} [label="default"] 计时器名称 / Timer label.
261
+ * @returns {Map<string, number>}
262
+ */
160
263
  static time = (label = "default") => Console.#times.set(label, Date.now());
161
264
 
265
+ /**
266
+ * 结束计时并移除计时器。
267
+ * End timer and remove it.
268
+ *
269
+ * @param {string} [label="default"] 计时器名称 / Timer label.
270
+ * @returns {boolean}
271
+ */
162
272
  static timeEnd = (label = "default") => Console.#times.delete(label);
163
273
 
274
+ /**
275
+ * 输出当前计时器耗时。
276
+ * Print elapsed time for a timer.
277
+ *
278
+ * @param {string} [label="default"] 计时器名称 / Timer label.
279
+ * @returns {void}
280
+ */
164
281
  static timeLog = (label = "default") => {
165
282
  const time = Console.#times.get(label);
166
283
  if (time) Console.log(`${label}: ${Date.now() - time}ms`);
167
284
  else Console.warn(`Timer "${label}" doesn’t exist`);
168
285
  };
169
286
 
287
+ /**
288
+ * 输出警告日志。
289
+ * Print warning logs.
290
+ *
291
+ * @param {...any} msg 日志内容 / Log messages.
292
+ * @returns {void}
293
+ */
170
294
  static warn(...msg) {
171
295
  if (Console.#level < 2) return;
172
296
  msg = msg.map(m => `⚠️ ${m}`);
@@ -1,5 +1,28 @@
1
1
  /* https://www.lodashjs.com */
2
+ /**
3
+ * 轻量 Lodash 工具集。
4
+ * Lightweight Lodash-like utilities.
5
+ *
6
+ * 说明:
7
+ * Notes:
8
+ * - 这是 Lodash 的“部分方法”简化实现,不等价于完整 Lodash
9
+ * - This is a simplified subset, not a full Lodash implementation
10
+ * - 各方法语义可参考 Lodash 官方文档
11
+ * - Method semantics can be referenced from official Lodash docs
12
+ *
13
+ * 参考:
14
+ * Reference:
15
+ * - https://www.lodashjs.com
16
+ * - https://lodash.com
17
+ */
2
18
  export class Lodash {
19
+ /**
20
+ * HTML 特殊字符转义。
21
+ * Escape HTML special characters.
22
+ *
23
+ * @param {string} string 输入文本 / Input text.
24
+ * @returns {string}
25
+ */
3
26
  static escape(string) {
4
27
  const map = {
5
28
  "&": "&amp;",
@@ -11,6 +34,15 @@ export class Lodash {
11
34
  return string.replace(/[&<>"']/g, m => map[m]);
12
35
  }
13
36
 
37
+ /**
38
+ * 按路径读取对象值。
39
+ * Get object value by path.
40
+ *
41
+ * @param {object} [object={}] 目标对象 / Target object.
42
+ * @param {string|string[]} [path=""] 路径 / Path.
43
+ * @param {*} [defaultValue=undefined] 默认值 / Default value.
44
+ * @returns {*}
45
+ */
14
46
  static get(object = {}, path = "", defaultValue = undefined) {
15
47
  // translate array case to dot case, then split with .
16
48
  // a[0].b -> a.0.b -> ['a', '0', 'b']
@@ -24,7 +56,9 @@ export class Lodash {
24
56
 
25
57
  /**
26
58
  * 递归合并源对象的自身可枚举属性到目标对象
59
+ * Recursively merge source enumerable properties into target object.
27
60
  * @description 简化版 lodash.merge,用于合并配置对象
61
+ * @description A simplified lodash.merge for config merging.
28
62
  *
29
63
  * 适用情况:
30
64
  * - 合并嵌套的配置/设置对象
@@ -41,8 +75,11 @@ export class Lodash {
41
75
  * - 会修改原始目标对象 (mutates target)
42
76
  *
43
77
  * @param {object} object - 目标对象
78
+ * @param {object} object - Target object.
44
79
  * @param {...object} sources - 源对象(可多个)
80
+ * @param {...object} sources - Source objects.
45
81
  * @returns {object} 返回合并后的目标对象
82
+ * @returns {object} Merged target object.
46
83
  * @example
47
84
  * const target = { a: { b: 1 }, c: 2 };
48
85
  * const source = { a: { d: 3 }, e: 4 };
@@ -99,8 +136,11 @@ export class Lodash {
99
136
 
100
137
  /**
101
138
  * 判断值是否为普通对象 (Plain Object)
139
+ * Check whether a value is a plain object.
102
140
  * @param {*} value - 要检查的值
141
+ * @param {*} value - Value to check.
103
142
  * @returns {boolean} 如果是普通对象返回 true
143
+ * @returns {boolean} Returns true when value is a plain object.
104
144
  */
105
145
  static #isPlainObject(value) {
106
146
  if (value === null || typeof value !== "object") return false;
@@ -108,24 +148,56 @@ export class Lodash {
108
148
  return proto === null || proto === Object.prototype;
109
149
  }
110
150
 
151
+ /**
152
+ * 删除对象指定路径并返回对象。
153
+ * Omit paths from object and return the same object.
154
+ *
155
+ * @param {object} [object={}] 目标对象 / Target object.
156
+ * @param {string|string[]} [paths=[]] 要删除的路径 / Paths to remove.
157
+ * @returns {object}
158
+ */
111
159
  static omit(object = {}, paths = []) {
112
160
  if (!Array.isArray(paths)) paths = [paths.toString()];
113
161
  paths.forEach(path => Lodash.unset(object, path));
114
162
  return object;
115
163
  }
116
164
 
165
+ /**
166
+ * 仅保留对象指定键(第一层)。
167
+ * Pick selected keys from object (top level only).
168
+ *
169
+ * @param {object} [object={}] 目标对象 / Target object.
170
+ * @param {string|string[]} [paths=[]] 需要保留的键 / Keys to keep.
171
+ * @returns {object}
172
+ */
117
173
  static pick(object = {}, paths = []) {
118
174
  if (!Array.isArray(paths)) paths = [paths.toString()];
119
175
  const filteredEntries = Object.entries(object).filter(([key, value]) => paths.includes(key));
120
176
  return Object.fromEntries(filteredEntries);
121
177
  }
122
178
 
179
+ /**
180
+ * 按路径写入对象值。
181
+ * Set object value by path.
182
+ *
183
+ * @param {object} object 目标对象 / Target object.
184
+ * @param {string|string[]} path 路径 / Path.
185
+ * @param {*} value 写入值 / Value.
186
+ * @returns {object}
187
+ */
123
188
  static set(object, path, value) {
124
189
  if (!Array.isArray(path)) path = Lodash.toPath(path);
125
190
  path.slice(0, -1).reduce((previousValue, currentValue, currentIndex) => (Object(previousValue[currentValue]) === previousValue[currentValue] ? previousValue[currentValue] : (previousValue[currentValue] = /^\d+$/.test(path[currentIndex + 1]) ? [] : {})), object)[path[path.length - 1]] = value;
126
191
  return object;
127
192
  }
128
193
 
194
+ /**
195
+ * 将点路径或数组下标路径转换为数组。
196
+ * Convert dot/array-index path string into path segments.
197
+ *
198
+ * @param {string} value 路径字符串 / Path string.
199
+ * @returns {string[]}
200
+ */
129
201
  static toPath(value) {
130
202
  return value
131
203
  .replace(/\[(\d+)\]/g, ".$1")
@@ -133,6 +205,13 @@ export class Lodash {
133
205
  .filter(Boolean);
134
206
  }
135
207
 
208
+ /**
209
+ * HTML 实体反转义。
210
+ * Unescape HTML entities.
211
+ *
212
+ * @param {string} string 输入文本 / Input text.
213
+ * @returns {string}
214
+ */
136
215
  static unescape(string) {
137
216
  const map = {
138
217
  "&amp;": "&",
@@ -144,6 +223,14 @@ export class Lodash {
144
223
  return string.replace(/&amp;|&lt;|&gt;|&quot;|&#39;/g, m => map[m]);
145
224
  }
146
225
 
226
+ /**
227
+ * 删除对象路径对应的值。
228
+ * Remove value by object path.
229
+ *
230
+ * @param {object} [object={}] 目标对象 / Target object.
231
+ * @param {string|string[]} [path=""] 路径 / Path.
232
+ * @returns {boolean}
233
+ */
147
234
  static unset(object = {}, path = "") {
148
235
  if (!Array.isArray(path)) path = Lodash.toPath(path);
149
236
  const result = path.reduce((previousValue, currentValue, currentIndex) => {
@@ -1,3 +1,20 @@
1
+ /**
2
+ * HTTP 状态码文本映射表。
3
+ * HTTP status code to status text map.
4
+ *
5
+ * 主要用途:
6
+ * Primary usage:
7
+ * - 为 Quantumult X 的 `$done` 状态行拼接提供状态文本
8
+ * - Provide status text for Quantumult X `$done` status-line composition
9
+ * - QX 在部分场景要求 `status` 为完整状态行(如 `HTTP/1.1 200 OK`)
10
+ * - QX may require full status line (e.g. `HTTP/1.1 200 OK`) in some cases
11
+ *
12
+ * 参考:
13
+ * Reference:
14
+ * - https://github.com/crossutility/Quantumult-X/raw/refs/heads/master/sample-rewrite-response-header.js
15
+ *
16
+ * @type {Record<number, string>}
17
+ */
1
18
  export const StatusTexts = {
2
19
  100: "Continue",
3
20
  101: "Switching Protocols",