@nsnanocat/util 2.1.0 → 2.1.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/README.md +653 -1
- package/getStorage.mjs +76 -27
- package/index.js +12 -1
- package/lib/app.mjs +13 -2
- package/lib/argument.mjs +38 -8
- package/lib/done.mjs +23 -3
- package/lib/environment.mjs +22 -0
- package/lib/index.js +12 -0
- package/lib/notification.mjs +40 -11
- package/lib/runScript.mjs +21 -0
- package/lib/time.mjs +9 -9
- package/lib/wait.mjs +4 -4
- package/package.json +1 -1
- package/polyfill/Console.mjs +124 -0
- package/polyfill/Lodash.mjs +109 -0
- package/polyfill/StatusTexts.mjs +17 -0
- package/polyfill/Storage.mjs +76 -29
- package/polyfill/fetch.mjs +61 -6
package/getStorage.mjs
CHANGED
|
@@ -4,49 +4,82 @@ import { Lodash as _ } from "./polyfill/Lodash.mjs";
|
|
|
4
4
|
import { Storage } from "./polyfill/Storage.mjs";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* 存储配置读取与合并结果。
|
|
8
|
+
* Merged storage result object.
|
|
9
|
+
*
|
|
10
|
+
* @typedef {object} StorageProfile
|
|
11
|
+
* @property {Record<string, any>} Settings 运行设置 / Runtime settings.
|
|
12
|
+
* @property {Record<string, any>} Configs 静态配置 / Static configs.
|
|
13
|
+
* @property {Record<string, any>} Caches 缓存数据 / Runtime caches.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 读取并合并默认配置、持久化配置与 `$argument`。
|
|
18
|
+
* Read and merge default config, persisted config and `$argument`.
|
|
19
|
+
*
|
|
20
|
+
* 合并来源与顺序由 `$argument.Storage` 控制:
|
|
21
|
+
* Merge source order is controlled by `$argument.Storage`:
|
|
22
|
+
* - `undefined`(默认): `database[name]` -> `$argument` -> `PersistentStore[name]`
|
|
23
|
+
* - `$argument`: `database[name]` -> `PersistentStore[name]` -> `$argument`
|
|
24
|
+
* - `PersistentStore` / `BoxJs`: `database[name]` -> `PersistentStore[name]`
|
|
25
|
+
* - `database`: 仅 `database[name]`
|
|
26
|
+
*
|
|
8
27
|
* @link https://github.com/NanoCat-Me/utils/blob/main/getStorage.mjs
|
|
9
28
|
* @author VirgilClyne
|
|
10
|
-
* @param {string} key
|
|
11
|
-
* @param {
|
|
12
|
-
* @param {
|
|
13
|
-
* @
|
|
29
|
+
* @param {string} key 持久化主键 / Persistent store key.
|
|
30
|
+
* @param {string|string[]|Array<string|string[]>} names 目标配置名 / Target profile names.
|
|
31
|
+
* @param {Record<string, any>} database 默认数据库 / Default database object.
|
|
32
|
+
* @returns {StorageProfile}
|
|
14
33
|
*/
|
|
15
34
|
export function getStorage(key, names, database) {
|
|
16
35
|
if (database?.Default?.Settings?.LogLevel) Console.logLevel = database.Default.Settings.LogLevel;
|
|
17
36
|
Console.debug("☑️ getStorage");
|
|
18
37
|
names = [names].flat(Number.POSITIVE_INFINITY);
|
|
19
38
|
/***************** Default *****************/
|
|
20
|
-
const
|
|
21
|
-
Console.debug("Default", `
|
|
22
|
-
/*****************
|
|
39
|
+
const Root = { Settings: database?.Default?.Settings || {}, Configs: database?.Default?.Configs || {}, Caches: {} };
|
|
40
|
+
Console.debug("Default", `Root.Settings类型: ${typeof Root.Settings}`, `Root.Settings: ${JSON.stringify(Root.Settings)}`);
|
|
41
|
+
/***************** PersistentStore *****************/
|
|
23
42
|
// 包装为局部变量,用完释放内存
|
|
24
|
-
// BoxJs的清空操作返回假值空字符串, 逻辑或操作符会在左侧操作数为假值时返回右侧操作数。
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
27
|
-
Console.debug("☑️
|
|
43
|
+
// BoxJs 的清空操作返回假值空字符串, 逻辑或操作符会在左侧操作数为假值时返回右侧操作数。
|
|
44
|
+
const PersistentStore = Storage.getItem(key, {});
|
|
45
|
+
if (PersistentStore) {
|
|
46
|
+
Console.debug("☑️ PersistentStore", `PersistentStore类型: ${typeof PersistentStore}`, `PersistentStore内容: ${JSON.stringify(PersistentStore || {})}`);
|
|
28
47
|
names.forEach(name => {
|
|
29
|
-
if (typeof
|
|
30
|
-
|
|
48
|
+
if (typeof PersistentStore?.[name]?.Settings === "string") {
|
|
49
|
+
PersistentStore[name].Settings = JSON.parse(PersistentStore[name].Settings || "{}");
|
|
31
50
|
}
|
|
32
|
-
if (typeof
|
|
33
|
-
|
|
51
|
+
if (typeof PersistentStore?.[name]?.Caches === "string") {
|
|
52
|
+
PersistentStore[name].Caches = JSON.parse(PersistentStore[name].Caches || "{}");
|
|
34
53
|
}
|
|
35
54
|
});
|
|
36
|
-
if (
|
|
37
|
-
Console.debug("✅
|
|
55
|
+
if (PersistentStore.LogLevel) Console.logLevel = PersistentStore.LogLevel;
|
|
56
|
+
Console.debug("✅ PersistentStore", `Root.Settings类型: ${typeof Root.Settings}`, `Root.Settings: ${JSON.stringify(Root.Settings)}`);
|
|
38
57
|
}
|
|
39
58
|
/***************** Merge *****************/
|
|
40
59
|
names.forEach(name => {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
60
|
+
switch ($argument.Storage) {
|
|
61
|
+
case "$argument":
|
|
62
|
+
_.merge(Root.Settings, database?.[name]?.Settings, PersistentStore?.[name]?.Settings, $argument);
|
|
63
|
+
break;
|
|
64
|
+
case "BoxJs":
|
|
65
|
+
case "PersistentStore":
|
|
66
|
+
_.merge(Root.Settings, database?.[name]?.Settings, PersistentStore?.[name]?.Settings);
|
|
67
|
+
break;
|
|
68
|
+
case "database":
|
|
69
|
+
_.merge(Root.Settings, database?.[name]?.Settings);
|
|
70
|
+
break;
|
|
71
|
+
default:
|
|
72
|
+
case undefined:
|
|
73
|
+
_.merge(Root.Settings, database?.[name]?.Settings, $argument, PersistentStore?.[name]?.Settings);
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
_.merge(Root.Configs, database?.[name]?.Configs);
|
|
77
|
+
_.merge(Root.Caches, PersistentStore?.[name]?.Caches);
|
|
44
78
|
});
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
Console.debug("✅ Merge", `Store.Settings类型: ${typeof Store.Settings}`, `Store.Settings: ${JSON.stringify(Store.Settings)}`);
|
|
79
|
+
if (Root.Settings.LogLevel) Console.logLevel = Root.Settings.LogLevel;
|
|
80
|
+
Console.debug("✅ Merge", `Root.Settings类型: ${typeof Root.Settings}`, `Root.Settings: ${JSON.stringify(Root.Settings)}`);
|
|
48
81
|
/***************** traverseObject *****************/
|
|
49
|
-
traverseObject(
|
|
82
|
+
traverseObject(Root.Settings, (key, value) => {
|
|
50
83
|
Console.debug("☑️ traverseObject", `${key}: ${typeof value}`, `${key}: ${JSON.stringify(value)}`);
|
|
51
84
|
if (value === "true" || value === "false")
|
|
52
85
|
value = JSON.parse(value); // 字符串转Boolean
|
|
@@ -57,11 +90,19 @@ export function getStorage(key, names, database) {
|
|
|
57
90
|
}
|
|
58
91
|
return value;
|
|
59
92
|
});
|
|
60
|
-
Console.debug("✅ traverseObject", `
|
|
93
|
+
Console.debug("✅ traverseObject", `Root.Settings类型: ${typeof Root.Settings}`, `Root.Settings: ${JSON.stringify(Root.Settings)}`);
|
|
61
94
|
Console.debug("✅ getStorage");
|
|
62
|
-
return
|
|
95
|
+
return Root;
|
|
63
96
|
}
|
|
64
97
|
|
|
98
|
+
/**
|
|
99
|
+
* 深度遍历对象并用回调替换叶子值。
|
|
100
|
+
* Deep-walk an object and replace leaf values using callback.
|
|
101
|
+
*
|
|
102
|
+
* @param {Record<string, any>} o 目标对象 / Target object.
|
|
103
|
+
* @param {(key: string, value: any) => any} c 处理回调 / Transformer callback.
|
|
104
|
+
* @returns {Record<string, any>}
|
|
105
|
+
*/
|
|
65
106
|
function traverseObject(o, c) {
|
|
66
107
|
for (const t in o) {
|
|
67
108
|
const n = o[t];
|
|
@@ -69,6 +110,14 @@ function traverseObject(o, c) {
|
|
|
69
110
|
}
|
|
70
111
|
return o;
|
|
71
112
|
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 将纯数字字符串转换为数字。
|
|
116
|
+
* Convert integer-like string into number.
|
|
117
|
+
*
|
|
118
|
+
* @param {string} string 输入字符串 / Input string.
|
|
119
|
+
* @returns {string|number}
|
|
120
|
+
*/
|
|
72
121
|
function string2number(string) {
|
|
73
122
|
if (/^\d+$/.test(string)) string = Number.parseInt(string, 10);
|
|
74
123
|
return string;
|
package/index.js
CHANGED
|
@@ -9,4 +9,15 @@ export * from "./polyfill/fetch.mjs";
|
|
|
9
9
|
export * from "./polyfill/Lodash.mjs";
|
|
10
10
|
export * from "./polyfill/StatusTexts.mjs";
|
|
11
11
|
export * from "./polyfill/Storage.mjs";
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 已标准化的 `$argument` 快照。
|
|
15
|
+
* Normalized `$argument` snapshot.
|
|
16
|
+
*/
|
|
17
|
+
export const $argument = globalThis.$argument ?? {};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 兼容别名(建议优先使用 `$argument`)。
|
|
21
|
+
* Backward-compatible alias (prefer `$argument`).
|
|
22
|
+
*/
|
|
23
|
+
export const argument = $argument;
|
package/lib/app.mjs
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 当前运行平台名称。
|
|
3
|
+
* Current runtime platform name.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
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,24 +1,54 @@
|
|
|
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
|
+
*
|
|
22
|
+
* 归一化规则补充:
|
|
23
|
+
* Normalization details:
|
|
24
|
+
* - 使用 `globalThis.$argument` 读写,避免运行环境下未声明变量引用问题
|
|
25
|
+
* - Read/write via `globalThis.$argument` to avoid undeclared variable access
|
|
26
|
+
* - 当 `$argument` 为 `null` 或 `undefined` 时,会重置为 `{}`
|
|
27
|
+
* - When `$argument` is `null` or `undefined`, it is normalized to `{}`
|
|
28
|
+
*/
|
|
4
29
|
(() => {
|
|
5
30
|
Console.debug("☑️ $argument");
|
|
6
|
-
switch (typeof
|
|
31
|
+
switch (typeof globalThis.$argument) {
|
|
7
32
|
case "string": {
|
|
8
|
-
const argument = Object.fromEntries(
|
|
9
|
-
|
|
10
|
-
Object.keys(argument).forEach(key => _.set(
|
|
33
|
+
const argument = Object.fromEntries(globalThis.$argument.split("&").map(item => item.split("=", 2).map(i => i.replace(/\"/g, ""))));
|
|
34
|
+
globalThis.$argument = {};
|
|
35
|
+
Object.keys(argument).forEach(key => _.set(globalThis.$argument, key, argument[key]));
|
|
11
36
|
break;
|
|
12
37
|
}
|
|
13
38
|
case "object": {
|
|
39
|
+
if (globalThis.$argument === null) {
|
|
40
|
+
globalThis.$argument = {};
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
14
43
|
const argument = {};
|
|
15
|
-
Object.keys(
|
|
16
|
-
|
|
44
|
+
Object.keys(globalThis.$argument).forEach(key => _.set(argument, key, globalThis.$argument[key]));
|
|
45
|
+
globalThis.$argument = argument;
|
|
17
46
|
break;
|
|
18
47
|
}
|
|
19
48
|
case "undefined":
|
|
49
|
+
globalThis.$argument = {};
|
|
20
50
|
break;
|
|
21
51
|
}
|
|
22
|
-
if (
|
|
23
|
-
Console.debug("✅ $argument", `$argument: ${JSON.stringify(
|
|
52
|
+
if (globalThis.$argument.LogLevel) Console.logLevel = globalThis.$argument.LogLevel;
|
|
53
|
+
Console.debug("✅ $argument", `$argument: ${JSON.stringify(globalThis.$argument)}`);
|
|
24
54
|
})();
|
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
|
-
*
|
|
7
|
+
* `done` 的统一入参结构。
|
|
8
|
+
* Unified `done` input payload.
|
|
8
9
|
*
|
|
9
|
-
* @
|
|
10
|
-
* @
|
|
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 = {}) {
|
package/lib/environment.mjs
CHANGED
|
@@ -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;
|
package/lib/notification.mjs
CHANGED
|
@@ -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
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
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
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
2
|
+
* 延时等待指定毫秒后继续执行。
|
|
3
|
+
* Wait for the given milliseconds before continuing.
|
|
3
4
|
*
|
|
4
|
-
* @
|
|
5
|
-
* @
|
|
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