@nsnanocat/util 2.1.4 → 2.1.7
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 +25 -5
- package/getStorage.mjs +39 -9
- package/package.json +4 -2
- package/polyfill/Storage.mjs +10 -2
- package/types/nsnanocat-util.d.ts +143 -0
package/README.md
CHANGED
|
@@ -87,7 +87,7 @@ import {
|
|
|
87
87
|
### 仓库中存在但未从主入口导出
|
|
88
88
|
- `lib/environment.mjs`
|
|
89
89
|
- `lib/runScript.mjs`
|
|
90
|
-
- `getStorage.mjs
|
|
90
|
+
- `getStorage.mjs`(薯条项目自用,仅当你的存储结构与薯条项目一致时再使用;请通过子路径 `@nsnanocat/util/getStorage.mjs` 导入)
|
|
91
91
|
|
|
92
92
|
## 模块依赖关系
|
|
93
93
|
|
|
@@ -331,7 +331,25 @@ await runScript("$done({})", { timeout: 20 });
|
|
|
331
331
|
|
|
332
332
|
示例:
|
|
333
333
|
```js
|
|
334
|
-
import
|
|
334
|
+
import getStorage from "@nsnanocat/util/getStorage.mjs";
|
|
335
|
+
|
|
336
|
+
const store = getStorage("@my_box", ["YouTube", "Global"], database);
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
#### 命名导出(辅助函数)
|
|
340
|
+
|
|
341
|
+
`getStorage.mjs` 同时导出以下辅助函数:
|
|
342
|
+
- `traverseObject(o, c)`:深度遍历对象并替换叶子值
|
|
343
|
+
- `string2number(string)`:将纯数字字符串转换为数字
|
|
344
|
+
- `value2array(value)`:字符串按逗号拆分;数字/布尔值会被包装为单元素数组
|
|
345
|
+
|
|
346
|
+
示例:
|
|
347
|
+
```js
|
|
348
|
+
import getStorage, {
|
|
349
|
+
traverseObject,
|
|
350
|
+
string2number,
|
|
351
|
+
value2array,
|
|
352
|
+
} from "@nsnanocat/util/getStorage.mjs";
|
|
335
353
|
|
|
336
354
|
const store = getStorage("@my_box", ["YouTube", "Global"], database);
|
|
337
355
|
```
|
|
@@ -412,10 +430,12 @@ const store = getStorage("@my_box", ["YouTube", "Global"], database);
|
|
|
412
430
|
#### `Storage.removeItem(keyName)`
|
|
413
431
|
- Quantumult X:可用(`$prefs.removeValueForKey`)。
|
|
414
432
|
- Surge:通过 `$persistentStore.write(null, keyName)` 删除。
|
|
415
|
-
-
|
|
433
|
+
- Node.js:可用(删除 `box.dat` 中对应 key 并落盘)。
|
|
434
|
+
- Loon / Stash / Egern / Shadowrocket:返回 `false`。
|
|
416
435
|
|
|
417
436
|
#### `Storage.clear()`
|
|
418
437
|
- Quantumult X:可用(`$prefs.removeAllValues`)。
|
|
438
|
+
- Node.js:可用(清空 `box.dat` 并落盘)。
|
|
419
439
|
- 其他平台:返回 `false`。
|
|
420
440
|
|
|
421
441
|
#### Node.js 特性
|
|
@@ -424,7 +444,7 @@ const store = getStorage("@my_box", ["YouTube", "Global"], database);
|
|
|
424
444
|
|
|
425
445
|
与 Web Storage 的行为差异:
|
|
426
446
|
- 支持 `@key.path` 深路径读写(Web Storage 原生不支持)。
|
|
427
|
-
- `removeItem/clear` 仅部分平台可用(目前为 Quantumult X,以及 Surge 的 `removeItem`)。
|
|
447
|
+
- `removeItem/clear` 仅部分平台可用(目前为 Quantumult X、Node.js,以及 Surge 的 `removeItem`)。
|
|
428
448
|
- `getItem` 会尝试 `JSON.parse`,`setItem` 写入对象会 `JSON.stringify`。
|
|
429
449
|
|
|
430
450
|
平台后端映射:
|
|
@@ -604,7 +624,7 @@ console.log(value); // 1
|
|
|
604
624
|
| 通知 | `$notify` | `$notification.post` | `$notification.post` | `$notification.post` | `$notification.post` | `$notification.post` | 无 |
|
|
605
625
|
| 持久化 | `$prefs` | `$persistentStore` | `$persistentStore` | `$persistentStore` | `$persistentStore` | `$persistentStore` | `box.dat` |
|
|
606
626
|
| 结束脚本 | `$done` | `$done` | `$done` | `$done` | `$done` | `$done` | `process.exit(1)` |
|
|
607
|
-
| `removeItem/clear` | 可用 | 不可用 | `removeItem` 可用 / `clear` 不可用 | 不可用 | 不可用 | 不可用 |
|
|
627
|
+
| `removeItem/clear` | 可用 | 不可用 | `removeItem` 可用 / `clear` 不可用 | 不可用 | 不可用 | 不可用 | 可用 |
|
|
608
628
|
| `policy` 注入(`fetch/done`) | `opts.policy` | `node` | `X-Surge-Policy`(done) | `X-Stash-Selected-Proxy` | 无专门映射 | `X-Surge-Proxy`(fetch) | 无 |
|
|
609
629
|
|
|
610
630
|
## 已知限制与注意事项
|
package/getStorage.mjs
CHANGED
|
@@ -36,8 +36,11 @@ import { Storage } from "./polyfill/Storage.mjs";
|
|
|
36
36
|
* @param {string|string[]|Array<string|string[]>} names 目标配置名 / Target profile names.
|
|
37
37
|
* @param {Record<string, any>} database 默认数据库 / Default database object.
|
|
38
38
|
* @returns {StorageProfile}
|
|
39
|
+
*
|
|
40
|
+
* @module getStorage
|
|
41
|
+
* @default
|
|
39
42
|
*/
|
|
40
|
-
export function getStorage(key, names, database) {
|
|
43
|
+
export default function getStorage(key, names, database) {
|
|
41
44
|
if (database?.Default?.Settings?.LogLevel) Console.logLevel = database.Default.Settings.LogLevel;
|
|
42
45
|
Console.debug("☑️ getStorage");
|
|
43
46
|
names = [names].flat(Number.POSITIVE_INFINITY);
|
|
@@ -103,12 +106,20 @@ export function getStorage(key, names, database) {
|
|
|
103
106
|
/***************** traverseObject *****************/
|
|
104
107
|
traverseObject(Root.Settings, (key, value) => {
|
|
105
108
|
Console.debug("☑️ traverseObject", `${key}: ${typeof value}`, `${key}: ${JSON.stringify(value)}`);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
switch (typeof value) {
|
|
110
|
+
case "string":
|
|
111
|
+
switch (value) {
|
|
112
|
+
case "true":
|
|
113
|
+
case "false":
|
|
114
|
+
case "[]":
|
|
115
|
+
value = JSON.parse(value); // 字符串转Boolean/空数组
|
|
116
|
+
break;
|
|
117
|
+
default:
|
|
118
|
+
if (value.includes(","))
|
|
119
|
+
value = value2array(value).map(item => string2number(item)); // 字符串转数组转数字
|
|
120
|
+
else value = string2number(value); // 字符串转数字
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
112
123
|
}
|
|
113
124
|
return value;
|
|
114
125
|
});
|
|
@@ -125,7 +136,7 @@ export function getStorage(key, names, database) {
|
|
|
125
136
|
* @param {(key: string, value: any) => any} c 处理回调 / Transformer callback.
|
|
126
137
|
* @returns {Record<string, any>}
|
|
127
138
|
*/
|
|
128
|
-
function traverseObject(o, c) {
|
|
139
|
+
export function traverseObject(o, c) {
|
|
129
140
|
for (const t in o) {
|
|
130
141
|
const n = o[t];
|
|
131
142
|
o[t] = "object" === typeof n && null !== n ? traverseObject(n, c) : c(t, n);
|
|
@@ -140,7 +151,26 @@ function traverseObject(o, c) {
|
|
|
140
151
|
* @param {string} string 输入字符串 / Input string.
|
|
141
152
|
* @returns {string|number}
|
|
142
153
|
*/
|
|
143
|
-
function string2number(string) {
|
|
154
|
+
export function string2number(string) {
|
|
144
155
|
if (/^\d+$/.test(string)) string = Number.parseInt(string, 10);
|
|
145
156
|
return string;
|
|
146
157
|
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* 将值包装为数组。
|
|
161
|
+
* Split value into array.
|
|
162
|
+
*
|
|
163
|
+
* @param {string|number|boolean|string[]|null|undefined} value 输入值 / Input value.
|
|
164
|
+
* @returns {(string|number|boolean)[]}
|
|
165
|
+
*/
|
|
166
|
+
export function value2array(value) {
|
|
167
|
+
switch (typeof value) {
|
|
168
|
+
case "string":
|
|
169
|
+
return value.split(",");
|
|
170
|
+
case "number":
|
|
171
|
+
case "boolean":
|
|
172
|
+
return [value];
|
|
173
|
+
default:
|
|
174
|
+
return value || [];
|
|
175
|
+
}
|
|
176
|
+
}
|
package/package.json
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"license": "Apache-2.0",
|
|
15
15
|
"bugs": "https://github.com/NSNanoCat/util/issues",
|
|
16
16
|
"main": "index.js",
|
|
17
|
+
"types": "types/nsnanocat-util.d.ts",
|
|
17
18
|
"type": "module",
|
|
18
19
|
"scripts": {
|
|
19
20
|
"tsc:build": "npx tsc",
|
|
@@ -30,7 +31,8 @@
|
|
|
30
31
|
"index.js",
|
|
31
32
|
"lib",
|
|
32
33
|
"polyfill",
|
|
33
|
-
"getStorage.mjs"
|
|
34
|
+
"getStorage.mjs",
|
|
35
|
+
"types"
|
|
34
36
|
],
|
|
35
37
|
"devDependencies": {
|
|
36
38
|
"typescript": "^5.6.3"
|
|
@@ -39,5 +41,5 @@
|
|
|
39
41
|
"registry": "https://registry.npmjs.org/",
|
|
40
42
|
"access": "public"
|
|
41
43
|
},
|
|
42
|
-
"version": "2.1.
|
|
44
|
+
"version": "2.1.7"
|
|
43
45
|
}
|
package/polyfill/Storage.mjs
CHANGED
|
@@ -208,7 +208,11 @@ export class Storage {
|
|
|
208
208
|
result = $prefs.removeValueForKey(keyName);
|
|
209
209
|
break;
|
|
210
210
|
case "Node.js":
|
|
211
|
-
result = false;
|
|
211
|
+
// result = false;
|
|
212
|
+
Storage.data = Storage.#loaddata(Storage.dataFile);
|
|
213
|
+
delete Storage.data[keyName];
|
|
214
|
+
Storage.#writedata(Storage.dataFile);
|
|
215
|
+
result = true;
|
|
212
216
|
break;
|
|
213
217
|
default:
|
|
214
218
|
result = false;
|
|
@@ -239,7 +243,11 @@ export class Storage {
|
|
|
239
243
|
result = $prefs.removeAllValues();
|
|
240
244
|
break;
|
|
241
245
|
case "Node.js":
|
|
242
|
-
result = false;
|
|
246
|
+
// result = false;
|
|
247
|
+
Storage.data = Storage.#loaddata(Storage.dataFile);
|
|
248
|
+
Storage.data = {};
|
|
249
|
+
Storage.#writedata(Storage.dataFile);
|
|
250
|
+
result = true;
|
|
243
251
|
break;
|
|
244
252
|
default:
|
|
245
253
|
result = false;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
declare module "@nsnanocat/util" {
|
|
2
|
+
export type AppName = "Quantumult X" | "Loon" | "Shadowrocket" | "Node.js" | "Egern" | "Surge" | "Stash";
|
|
3
|
+
|
|
4
|
+
export const $app: AppName | undefined;
|
|
5
|
+
export const $argument: Record<string, unknown>;
|
|
6
|
+
export const argument: typeof $argument;
|
|
7
|
+
|
|
8
|
+
export interface DonePayload {
|
|
9
|
+
status?: number | string;
|
|
10
|
+
url?: string;
|
|
11
|
+
headers?: Record<string, unknown>;
|
|
12
|
+
body?: string | ArrayBuffer | ArrayBufferView;
|
|
13
|
+
bodyBytes?: ArrayBuffer;
|
|
14
|
+
policy?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function done(object?: DonePayload): void;
|
|
18
|
+
|
|
19
|
+
export interface NotificationContentObject {
|
|
20
|
+
open?: string;
|
|
21
|
+
"open-url"?: string;
|
|
22
|
+
url?: string;
|
|
23
|
+
openUrl?: string;
|
|
24
|
+
copy?: string;
|
|
25
|
+
"update-pasteboard"?: string;
|
|
26
|
+
updatePasteboard?: string;
|
|
27
|
+
media?: string;
|
|
28
|
+
"media-url"?: string;
|
|
29
|
+
mediaUrl?: string;
|
|
30
|
+
mime?: string;
|
|
31
|
+
"auto-dismiss"?: number;
|
|
32
|
+
sound?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type NotificationContent = NotificationContentObject | string | number | boolean;
|
|
36
|
+
|
|
37
|
+
export function notification(
|
|
38
|
+
title?: string,
|
|
39
|
+
subtitle?: string,
|
|
40
|
+
body?: string,
|
|
41
|
+
content?: NotificationContent,
|
|
42
|
+
): void;
|
|
43
|
+
|
|
44
|
+
export function time(format: string, ts?: number): string;
|
|
45
|
+
export function wait(delay?: number): Promise<void>;
|
|
46
|
+
|
|
47
|
+
export interface FetchRequest {
|
|
48
|
+
url: string;
|
|
49
|
+
method?: string;
|
|
50
|
+
headers?: Record<string, unknown>;
|
|
51
|
+
body?: string | ArrayBuffer | ArrayBufferView | object;
|
|
52
|
+
bodyBytes?: ArrayBuffer;
|
|
53
|
+
timeout?: number | string;
|
|
54
|
+
policy?: string;
|
|
55
|
+
redirection?: boolean;
|
|
56
|
+
"auto-redirect"?: boolean;
|
|
57
|
+
opts?: Record<string, unknown>;
|
|
58
|
+
[key: string]: unknown;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface FetchResponse {
|
|
62
|
+
ok: boolean;
|
|
63
|
+
status: number;
|
|
64
|
+
statusCode?: number;
|
|
65
|
+
statusText?: string;
|
|
66
|
+
headers?: Record<string, unknown>;
|
|
67
|
+
body?: string | ArrayBuffer;
|
|
68
|
+
bodyBytes?: ArrayBuffer;
|
|
69
|
+
[key: string]: unknown;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function fetch(resource: FetchRequest | string, options?: Partial<FetchRequest>): Promise<FetchResponse>;
|
|
73
|
+
|
|
74
|
+
export class Console {
|
|
75
|
+
static clear(): void;
|
|
76
|
+
static count(label?: string): void;
|
|
77
|
+
static countReset(label?: string): void;
|
|
78
|
+
static debug(...msg: unknown[]): void;
|
|
79
|
+
static error(...msg: unknown[]): void;
|
|
80
|
+
static exception(...msg: unknown[]): void;
|
|
81
|
+
static group(label: string): number;
|
|
82
|
+
static groupEnd(): string | undefined;
|
|
83
|
+
static info(...msg: unknown[]): void;
|
|
84
|
+
static get logLevel(): "OFF" | "ERROR" | "WARN" | "INFO" | "DEBUG" | "ALL";
|
|
85
|
+
static set logLevel(level: number | string);
|
|
86
|
+
static log(...msg: unknown[]): void;
|
|
87
|
+
static time(label?: string): Map<string, number>;
|
|
88
|
+
static timeEnd(label?: string): boolean;
|
|
89
|
+
static timeLog(label?: string): void;
|
|
90
|
+
static warn(...msg: unknown[]): void;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export class Lodash {
|
|
94
|
+
static escape(string: string): string;
|
|
95
|
+
static get<T = unknown, D = undefined>(object?: Record<string, unknown>, path?: string | string[], defaultValue?: D): T | D;
|
|
96
|
+
static merge<T extends Record<string, unknown>>(object: T, ...sources: Array<Record<string, unknown> | null | undefined>): T;
|
|
97
|
+
static omit<T extends Record<string, unknown>>(object?: T, paths?: string | string[]): T;
|
|
98
|
+
static pick<T extends Record<string, unknown>, K extends keyof T>(object?: T, paths?: K | K[]): Pick<T, K>;
|
|
99
|
+
static set<T extends Record<string, unknown>>(object: T, path: string | string[], value: unknown): T;
|
|
100
|
+
static toPath(value: string): string[];
|
|
101
|
+
static unescape(string: string): string;
|
|
102
|
+
static unset(object?: Record<string, unknown>, path?: string | string[]): boolean;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export const StatusTexts: Record<number, string>;
|
|
106
|
+
|
|
107
|
+
export class Storage {
|
|
108
|
+
static data: Record<string, unknown> | null;
|
|
109
|
+
static dataFile: string;
|
|
110
|
+
static getItem<T = unknown>(keyName: string, defaultValue?: T): T;
|
|
111
|
+
static setItem(keyName: string, keyValue: unknown): boolean;
|
|
112
|
+
static removeItem(keyName: string): boolean;
|
|
113
|
+
static clear(): boolean;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
declare module "@nsnanocat/util/getStorage.mjs" {
|
|
118
|
+
export interface StorageProfile {
|
|
119
|
+
Settings: Record<string, unknown>;
|
|
120
|
+
Configs: Record<string, unknown>;
|
|
121
|
+
Caches: Record<string, unknown>;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function traverseObject(
|
|
125
|
+
o: Record<string, unknown>,
|
|
126
|
+
c: (key: string, value: unknown) => unknown,
|
|
127
|
+
): Record<string, unknown>;
|
|
128
|
+
|
|
129
|
+
export function string2number(string: string): string | number;
|
|
130
|
+
|
|
131
|
+
export function value2array(value: string | number | boolean | string[] | null | undefined): Array<string | number | boolean>;
|
|
132
|
+
|
|
133
|
+
export default function getStorage(
|
|
134
|
+
key: string,
|
|
135
|
+
names: string | string[] | Array<string | string[]>,
|
|
136
|
+
database: Record<string, unknown>,
|
|
137
|
+
): StorageProfile;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
declare module "@nsnanocat/util/lib/environment.mjs" {
|
|
141
|
+
export const $environment: Record<string, unknown>;
|
|
142
|
+
export function environment(): Record<string, unknown>;
|
|
143
|
+
}
|