@nsnanocat/util 2.4.1 → 2.5.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 CHANGED
@@ -5,7 +5,7 @@
5
5
  核心目标:
6
6
  - 统一不同平台的 HTTP、通知、持久化、结束脚本等调用方式。
7
7
  - 在一个脚本里尽量少写平台分支。
8
- - 提供一组可直接复用的 polyfill(`fetch` / `Storage` / `KV` / `Console` / `Lodash` / `qs`)。
8
+ - 提供一组可直接复用的 polyfill(`fetch` / `Storage` / `Console` / `Lodash` / `qs`)。
9
9
 
10
10
  ## 目录
11
11
  - [安装与导入](#安装与导入)
@@ -65,7 +65,6 @@ import {
65
65
  wait, // 延时等待工具(Promise)
66
66
  Console, // 统一日志工具(支持 logLevel)
67
67
  Lodash as _, // Lodash 建议按官方示例惯例使用 `_` 作为工具对象别名
68
- KV, // Cloudflare Workers KV 异步适配器(显式传入 namespace binding)
69
68
  qs, // 查询字符串工具(parse / stringify)
70
69
  Storage, // 统一持久化存储接口(适配 $prefs / $persistentStore / 内存 / 文件)
71
70
  } from "@nsnanocat/util";
@@ -82,7 +81,6 @@ import {
82
81
  - `lib/wait.mjs`
83
82
  - `polyfill/Console.mjs`
84
83
  - `polyfill/fetch.mjs`
85
- - `polyfill/KV.mjs`
86
84
  - `polyfill/Lodash.mjs`
87
85
  - `polyfill/qs.mjs`
88
86
  - `polyfill/StatusTexts.mjs`
@@ -110,7 +108,6 @@ import {
110
108
  | `getStorage.mjs` | `lib/argument.mjs`, `polyfill/Console.mjs`, `polyfill/Lodash.mjs`, `polyfill/Storage.mjs` | `Console.debug`, `Console.logLevel`, `Lodash.merge`, `Storage.getItem` | 先标准化 `$argument`,再合并默认配置/持久化配置/运行参数 |
111
109
  | `polyfill/Console.mjs` | `lib/app.mjs` | `$app` | 日志在 Worker / Node.js 与 iOS 脚本环境使用不同错误输出策略 |
112
110
  | `polyfill/fetch.mjs` | `lib/app.mjs`, `polyfill/Lodash.mjs`, `polyfill/StatusTexts.mjs`, `polyfill/Console.mjs` | `$app`, `Lodash.set`, `StatusTexts`(`Console` 当前版本未实际调用) | 按平台选请求引擎并做参数映射、响应结构统一 |
113
- | `polyfill/KV.mjs` | `lib/app.mjs`, `polyfill/Lodash.mjs`, `polyfill/Storage.mjs` | `$app`, `Lodash.get`, `Lodash.set`, `Lodash.unset`, `Storage` | 为 Cloudflare Workers KV 提供异步适配,并在非 Worker 平台回退到 `Storage` |
114
111
  | `polyfill/Storage.mjs` | `lib/app.mjs`, `polyfill/Lodash.mjs` | `$app`, `Lodash.get`, `Lodash.set`, `Lodash.unset` | 按平台选持久化后端并支持 `@key.path` 读写 |
115
112
  | `polyfill/Lodash.mjs` | 无 | 无 | 提供路径/合并等基础能力,被多个模块复用 |
116
113
  | `polyfill/qs.mjs` | `polyfill/Lodash.mjs` | `Lodash.get`, `Lodash.set`, `Lodash.toPath` | 提供查询字符串与对象之间的解析/序列化能力 |
@@ -478,39 +475,6 @@ const store = getStorage("@my_box", ["YouTube", "Global"], database);
478
475
  | Worker | 进程内内存缓存 |
479
476
  | Node.js | 本地 `box.dat` |
480
477
 
481
- ### `polyfill/KV.mjs`
482
-
483
- `KV` 是面向 Cloudflare Workers KV 的异步适配器:
484
- - 调用方显式传入 namespace binding:`new KV(env.NAMESPACE)`
485
- - Worker 分支直接调用 `namespace.get/put/delete/list`
486
- - `get()` 不传 `type`,默认按 Cloudflare 行为读取字符串
487
- - 非 Worker 平台会回退到 `Storage.getItem/setItem/removeItem`
488
- - `list()` 仅支持 Worker,返回 Cloudflare KV 原生列举结果
489
- - `clear()` 始终返回 `false`
490
-
491
- #### `new KV(namespace)`
492
- - `namespace` 需提供 `get(key)` / `put(key, value)` / `delete(key)`。
493
-
494
- #### `await kv.getItem(keyName, defaultValue = null)`
495
- - 支持普通 key。
496
- - 支持路径 key:`@root.path.to.key`。
497
- - 读取后会尝试 `JSON.parse`。
498
-
499
- #### `await kv.setItem(keyName, keyValue)`
500
- - 支持普通 key 与路径 key。
501
- - `keyValue` 为对象时自动 `JSON.stringify`。
502
-
503
- #### `await kv.removeItem(keyName)`
504
- - 支持普通 key 与路径 key。
505
-
506
- #### `await kv.list(options = {})`
507
- - 仅支持 Worker。
508
- - 透传 `prefix` / `limit` / `cursor` 到 `namespace.list(options)`。
509
- - 返回 Cloudflare KV 的原生结果:`keys` / `list_complete` / `cursor`。
510
-
511
- #### `await kv.clear()`
512
- - 始终返回 `false`。
513
-
514
478
  ### `polyfill/Console.mjs`
515
479
 
516
480
  `Console` 是统一日志工具(静态类)。
package/index.js CHANGED
@@ -6,7 +6,6 @@ export * from "./lib/time.mjs";
6
6
  export * from "./lib/wait.mjs";
7
7
  export * from "./polyfill/Console.mjs";
8
8
  export * from "./polyfill/fetch.mjs";
9
- export * from "./polyfill/KV.mjs";
10
9
  export * from "./polyfill/Lodash.mjs";
11
10
  export * from "./polyfill/qs.mjs";
12
11
  export * from "./polyfill/StatusTexts.mjs";
package/package.json CHANGED
@@ -42,5 +42,5 @@
42
42
  "registry": "https://registry.npmjs.org/",
43
43
  "access": "public"
44
44
  },
45
- "version": "2.4.1"
45
+ "version": "2.5.2"
46
46
  }
@@ -0,0 +1,132 @@
1
+ /**
2
+ * 跨平台控制台输出适配器。
3
+ * Cross-platform console output adapter.
4
+ */
5
+ export class Console {
6
+ /**
7
+ * 清空控制台输出。
8
+ * Clear the console output.
9
+ */
10
+ static clear(): void;
11
+
12
+ /**
13
+ * 增加指定标签的计数。
14
+ * Increment the counter for the given label.
15
+ *
16
+ * @param label 计数标签 / Counter label.
17
+ */
18
+ static count(label?: string): void;
19
+
20
+ /**
21
+ * 重置指定标签的计数。
22
+ * Reset the counter for the given label.
23
+ *
24
+ * @param label 计数标签 / Counter label.
25
+ */
26
+ static countReset(label?: string): void;
27
+
28
+ /**
29
+ * 输出调试级别日志。
30
+ * Print debug-level log messages.
31
+ *
32
+ * @param msg 日志内容 / Log payloads.
33
+ */
34
+ static debug(...msg: unknown[]): void;
35
+
36
+ /**
37
+ * 输出错误级别日志。
38
+ * Print error-level log messages.
39
+ *
40
+ * @param msg 日志内容 / Log payloads.
41
+ */
42
+ static error(...msg: unknown[]): void;
43
+
44
+ /**
45
+ * 输出异常级别日志。
46
+ * Print exception-level log messages.
47
+ *
48
+ * @param msg 日志内容 / Log payloads.
49
+ */
50
+ static exception(...msg: unknown[]): void;
51
+
52
+ /**
53
+ * 开始一个日志分组。
54
+ * Start a log group.
55
+ *
56
+ * @param label 分组标签 / Group label.
57
+ * @returns 当前分组深度 / Current group depth.
58
+ */
59
+ static group(label: string): number;
60
+
61
+ /**
62
+ * 结束当前日志分组。
63
+ * End the current log group.
64
+ *
65
+ * @returns 已结束的分组标签 / Closed group label.
66
+ */
67
+ static groupEnd(): string | undefined;
68
+
69
+ /**
70
+ * 输出信息级别日志。
71
+ * Print info-level log messages.
72
+ *
73
+ * @param msg 日志内容 / Log payloads.
74
+ */
75
+ static info(...msg: unknown[]): void;
76
+
77
+ /**
78
+ * 获取当前日志级别。
79
+ * Get the current log level.
80
+ */
81
+ static get logLevel(): "OFF" | "ERROR" | "WARN" | "INFO" | "DEBUG" | "ALL";
82
+
83
+ /**
84
+ * 设置日志级别。
85
+ * Set the current log level.
86
+ *
87
+ * @param level 日志级别 / Log level.
88
+ */
89
+ static set logLevel(level: number | string);
90
+
91
+ /**
92
+ * 输出普通日志。
93
+ * Print standard log messages.
94
+ *
95
+ * @param msg 日志内容 / Log payloads.
96
+ */
97
+ static log(...msg: unknown[]): void;
98
+
99
+ /**
100
+ * 启动计时器。
101
+ * Start a timer.
102
+ *
103
+ * @param label 计时器标签 / Timer label.
104
+ * @returns 计时器映射表 / Timer map.
105
+ */
106
+ static time(label?: string): Map<string, number>;
107
+
108
+ /**
109
+ * 结束计时器并返回是否成功结束。
110
+ * End a timer and return whether it was closed.
111
+ *
112
+ * @param label 计时器标签 / Timer label.
113
+ * @returns 是否成功结束 / Whether the timer was closed.
114
+ */
115
+ static timeEnd(label?: string): boolean;
116
+
117
+ /**
118
+ * 输出计时器当前耗时。
119
+ * Print current elapsed time for a timer.
120
+ *
121
+ * @param label 计时器标签 / Timer label.
122
+ */
123
+ static timeLog(label?: string): void;
124
+
125
+ /**
126
+ * 输出警告级别日志。
127
+ * Print warn-level log messages.
128
+ *
129
+ * @param msg 日志内容 / Log payloads.
130
+ */
131
+ static warn(...msg: unknown[]): void;
132
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * 轻量 Lodash 风格工具集。
3
+ * Lightweight Lodash-style utility helpers.
4
+ */
5
+ export class Lodash {
6
+ /**
7
+ * 对 HTML 字符进行转义。
8
+ * Escape HTML characters.
9
+ *
10
+ * @param string 输入字符串 / Input string.
11
+ * @returns 转义后的字符串 / Escaped string.
12
+ */
13
+ static escape(string: string): string;
14
+
15
+ /**
16
+ * 读取对象中的嵌套路径值。
17
+ * Read a nested value from an object path.
18
+ *
19
+ * @param object 目标对象 / Target object.
20
+ * @param path 路径表达式 / Path expression.
21
+ * @param defaultValue 默认值 / Default value.
22
+ * @returns 路径值或默认值 / Path value or default.
23
+ */
24
+ static get<T = unknown, D = undefined>(object?: Record<string, unknown>, path?: string | string[], defaultValue?: D): T | D;
25
+
26
+ /**
27
+ * 深度合并对象。
28
+ * Deep-merge objects.
29
+ *
30
+ * @param object 目标对象 / Target object.
31
+ * @param sources 源对象列表 / Source objects.
32
+ * @returns 合并后的目标对象 / Merged target object.
33
+ */
34
+ static merge<T extends Record<string, unknown>>(object: T, ...sources: Array<Record<string, unknown> | null | undefined>): T;
35
+
36
+ /**
37
+ * 返回排除指定路径后的对象副本。
38
+ * Return a copy without specific paths.
39
+ *
40
+ * @param object 目标对象 / Target object.
41
+ * @param paths 排除路径 / Paths to omit.
42
+ * @returns 排除后的对象 / Object without omitted paths.
43
+ */
44
+ static omit<T extends Record<string, unknown>>(object?: T, paths?: string | string[]): T;
45
+
46
+ /**
47
+ * 返回仅包含指定路径的对象副本。
48
+ * Return a copy with only selected paths.
49
+ *
50
+ * @param object 目标对象 / Target object.
51
+ * @param paths 选择路径 / Paths to pick.
52
+ * @returns 仅保留指定路径的对象 / Object containing picked paths.
53
+ */
54
+ static pick<T extends Record<string, unknown>, K extends keyof T>(object?: T, paths?: K | K[]): Pick<T, K>;
55
+
56
+ /**
57
+ * 写入对象中的嵌套路径值。
58
+ * Set a nested value by path.
59
+ *
60
+ * @param object 目标对象 / Target object.
61
+ * @param path 路径表达式 / Path expression.
62
+ * @param value 写入值 / Value to set.
63
+ * @returns 修改后的目标对象 / Mutated target object.
64
+ */
65
+ static set<T extends Record<string, unknown>>(object: T, path: string | string[], value: unknown): T;
66
+
67
+ /**
68
+ * 将路径字符串转换为路径数组。
69
+ * Convert a path string to path segments.
70
+ *
71
+ * @param value 路径字符串 / Path string.
72
+ * @returns 路径数组 / Path segments.
73
+ */
74
+ static toPath(value: string): string[];
75
+
76
+ /**
77
+ * 还原 HTML 转义字符。
78
+ * Unescape HTML entities.
79
+ *
80
+ * @param string 输入字符串 / Input string.
81
+ * @returns 还原后的字符串 / Unescaped string.
82
+ */
83
+ static unescape(string: string): string;
84
+
85
+ /**
86
+ * 删除对象中的嵌套路径值。
87
+ * Delete a nested value by path.
88
+ *
89
+ * @param object 目标对象 / Target object.
90
+ * @param path 路径表达式 / Path expression.
91
+ * @returns 是否删除成功 / Whether deletion succeeded.
92
+ */
93
+ static unset(object?: Record<string, unknown>, path?: string | string[]): boolean;
94
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * HTTP 状态码文案映射表。
3
+ * HTTP status code text map.
4
+ */
5
+ export const StatusTexts: Record<number, string>;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * 跨平台持久化存储适配器。
3
+ * Cross-platform persistent storage adapter.
4
+ */
5
+ export class Storage {
6
+ /**
7
+ * 运行时缓存的数据对象。
8
+ * Runtime cached data object.
9
+ */
10
+ static data: Record<string, unknown> | null;
11
+
12
+ /**
13
+ * Node.js 分支持久化文件名。
14
+ * Persistent filename for Node.js branch.
15
+ */
16
+ static dataFile: string;
17
+
18
+ /**
19
+ * 读取指定键值。
20
+ * Read a value by key.
21
+ *
22
+ * @param keyName 键名 / Key name.
23
+ * @param defaultValue 默认值 / Default value.
24
+ * @returns 读取结果 / Read value.
25
+ */
26
+ static getItem<T = unknown>(keyName: string, defaultValue?: T): T;
27
+
28
+ /**
29
+ * 写入指定键值。
30
+ * Write a value by key.
31
+ *
32
+ * @param keyName 键名 / Key name.
33
+ * @param keyValue 写入值 / Value to write.
34
+ * @returns 是否写入成功 / Whether write succeeded.
35
+ */
36
+ static setItem(keyName: string, keyValue: unknown): boolean;
37
+
38
+ /**
39
+ * 删除指定键。
40
+ * Remove a value by key.
41
+ *
42
+ * @param keyName 键名 / Key name.
43
+ * @returns 是否删除成功 / Whether removal succeeded.
44
+ */
45
+ static removeItem(keyName: string): boolean;
46
+
47
+ /**
48
+ * 清空存储。
49
+ * Clear the storage.
50
+ *
51
+ * @returns 是否清空成功 / Whether clear succeeded.
52
+ */
53
+ static clear(): boolean;
54
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * 统一请求参数。
3
+ * Unified request payload.
4
+ */
5
+ export interface FetchRequest {
6
+ url: string;
7
+ method?: string;
8
+ headers?: Record<string, unknown>;
9
+ body?: string | ArrayBuffer | ArrayBufferView | object;
10
+ bodyBytes?: ArrayBuffer;
11
+ timeout?: number | string;
12
+ policy?: string;
13
+ redirection?: boolean;
14
+ "auto-redirect"?: boolean;
15
+ "auto-cookie"?: boolean | number | string;
16
+ opts?: Record<string, unknown>;
17
+ [key: string]: unknown;
18
+ }
19
+
20
+ /**
21
+ * 统一响应结构。
22
+ * Unified response payload.
23
+ */
24
+ export interface FetchResponse {
25
+ ok: boolean;
26
+ status: number;
27
+ statusCode?: number;
28
+ statusText?: string;
29
+ headers?: Record<string, unknown>;
30
+ body?: string | ArrayBuffer;
31
+ bodyBytes?: ArrayBuffer;
32
+ [key: string]: unknown;
33
+ }
34
+
35
+ /**
36
+ * 跨平台 `fetch` 函数签名。
37
+ * Cross-platform `fetch` function signature.
38
+ *
39
+ * @param resource 请求对象或 URL / Request object or URL string.
40
+ * @param options 追加参数 / Extra options.
41
+ * @returns 统一响应结构 / Normalized response payload.
42
+ */
43
+ export type Fetch = (resource: FetchRequest | string, options?: Partial<FetchRequest>) => Promise<FetchResponse>;
44
+
45
+ export const fetch: Fetch;
@@ -0,0 +1,6 @@
1
+ import { fetch as fetchRuntime } from "./fetch.mjs";
2
+ import type { Fetch } from "./fetch.d.ts";
3
+
4
+ export type { Fetch, FetchRequest, FetchResponse } from "./fetch.d.ts";
5
+
6
+ export const fetch: Fetch = fetchRuntime as Fetch;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Polyfill 模块聚合导出。
3
+ * Aggregated exports for polyfill modules.
4
+ */
5
+ export { Console } from "./Console.mjs";
6
+ export { fetch } from "./fetch.mjs";
7
+ export type { Fetch, FetchRequest, FetchResponse } from "./fetch.mjs";
8
+ export { Lodash } from "./Lodash.mjs";
9
+ export { qs } from "./qs.mjs";
10
+ export { StatusTexts } from "./StatusTexts.mjs";
11
+ export { Storage } from "./Storage.mjs";
package/polyfill/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  export * from "./Console.mjs";
2
2
  export * from "./fetch.mjs";
3
- export * from "./KV.mjs";
4
3
  export * from "./Lodash.mjs";
5
4
  export * from "./qs.mjs";
6
5
  export * from "./StatusTexts.mjs";
@@ -0,0 +1,23 @@
1
+ /**
2
+ * 查询字符串解析与序列化工具。
3
+ * Query string parser and serializer.
4
+ */
5
+ export class qs {
6
+ /**
7
+ * 将查询字符串或对象解析为规范对象。
8
+ * Parse a query string or object into a normalized object.
9
+ *
10
+ * @param query 查询输入 / Query input.
11
+ * @returns 解析结果对象 / Parsed object.
12
+ */
13
+ static parse(query?: string | Record<string, unknown> | null): Record<string, unknown>;
14
+
15
+ /**
16
+ * 将对象序列化为查询字符串。
17
+ * Serialize an object into a query string.
18
+ *
19
+ * @param object 输入对象 / Input object.
20
+ * @returns 序列化后的查询字符串 / Serialized query string.
21
+ */
22
+ static stringify(object?: Record<string, unknown>): string;
23
+ }
@@ -0,0 +1,7 @@
1
+ import type { Lodash as SharedLodash } from "../../polyfill/Lodash.d.ts";
2
+
3
+ declare module "@nsnanocat/util" {
4
+ export interface Lodash extends SharedLodash {}
5
+
6
+ export const Lodash: typeof import("../../polyfill/Lodash.d.ts").Lodash;
7
+ }
@@ -1,29 +1,9 @@
1
+ import type { Fetch as SharedFetch, FetchRequest as SharedFetchRequest, FetchResponse as SharedFetchResponse } from "../../polyfill/fetch.d.ts";
2
+
1
3
  declare module "@nsnanocat/util" {
2
- export interface FetchRequest {
3
- url: string;
4
- method?: string;
5
- headers?: Record<string, unknown>;
6
- body?: string | ArrayBuffer | ArrayBufferView | object;
7
- bodyBytes?: ArrayBuffer;
8
- timeout?: number | string;
9
- policy?: string;
10
- redirection?: boolean;
11
- "auto-redirect"?: boolean;
12
- "auto-cookie"?: boolean | number | string;
13
- opts?: Record<string, unknown>;
14
- [key: string]: unknown;
15
- }
4
+ export interface FetchRequest extends SharedFetchRequest {}
16
5
 
17
- export interface FetchResponse {
18
- ok: boolean;
19
- status: number;
20
- statusCode?: number;
21
- statusText?: string;
22
- headers?: Record<string, unknown>;
23
- body?: string | ArrayBuffer;
24
- bodyBytes?: ArrayBuffer;
25
- [key: string]: unknown;
26
- }
6
+ export interface FetchResponse extends SharedFetchResponse {}
27
7
 
28
- export function fetch(resource: FetchRequest | string, options?: Partial<FetchRequest>): Promise<FetchResponse>;
8
+ export const fetch: SharedFetch;
29
9
  }
@@ -1,40 +1,11 @@
1
- declare module "@nsnanocat/util" {
2
- export class Console {
3
- static clear(): void;
4
- static count(label?: string): void;
5
- static countReset(label?: string): void;
6
- static debug(...msg: unknown[]): void;
7
- static error(...msg: unknown[]): void;
8
- static exception(...msg: unknown[]): void;
9
- static group(label: string): number;
10
- static groupEnd(): string | undefined;
11
- static info(...msg: unknown[]): void;
12
- static get logLevel(): "OFF" | "ERROR" | "WARN" | "INFO" | "DEBUG" | "ALL";
13
- static set logLevel(level: number | string);
14
- static log(...msg: unknown[]): void;
15
- static time(label?: string): Map<string, number>;
16
- static timeEnd(label?: string): boolean;
17
- static timeLog(label?: string): void;
18
- static warn(...msg: unknown[]): void;
19
- }
1
+ import type { Console as SharedConsole } from "../../polyfill/Console.d.ts";
20
2
 
21
- export class Lodash {
22
- static escape(string: string): string;
23
- static get<T = unknown, D = undefined>(object?: Record<string, unknown>, path?: string | string[], defaultValue?: D): T | D;
24
- static merge<T extends Record<string, unknown>>(object: T, ...sources: Array<Record<string, unknown> | null | undefined>): T;
25
- static omit<T extends Record<string, unknown>>(object?: T, paths?: string | string[]): T;
26
- static pick<T extends Record<string, unknown>, K extends keyof T>(object?: T, paths?: K | K[]): Pick<T, K>;
27
- static set<T extends Record<string, unknown>>(object: T, path: string | string[], value: unknown): T;
28
- static toPath(value: string): string[];
29
- static unescape(string: string): string;
30
- static unset(object?: Record<string, unknown>, path?: string | string[]): boolean;
31
- }
3
+ type SharedStatusTexts = typeof import("../../polyfill/StatusTexts.d.ts").StatusTexts;
32
4
 
33
- export class qs {
34
- static parse(query?: string | Record<string, unknown> | null): Record<string, unknown>;
5
+ declare module "@nsnanocat/util" {
6
+ export interface Console extends SharedConsole {}
35
7
 
36
- static stringify(object?: Record<string, unknown>): string;
37
- }
8
+ export const Console: typeof import("../../polyfill/Console.d.ts").Console;
38
9
 
39
- export const StatusTexts: Record<number, string>;
10
+ export const StatusTexts: SharedStatusTexts;
40
11
  }
@@ -0,0 +1,7 @@
1
+ import type { qs as SharedQs } from "../../polyfill/qs.d.ts";
2
+
3
+ declare module "@nsnanocat/util" {
4
+ export interface qs extends SharedQs {}
5
+
6
+ export const qs: typeof import("../../polyfill/qs.d.ts").qs;
7
+ }
@@ -1,10 +1,7 @@
1
+ import type { Storage as SharedStorage } from "../../polyfill/Storage.d.ts";
2
+
1
3
  declare module "@nsnanocat/util" {
2
- export class Storage {
3
- static data: Record<string, unknown> | null;
4
- static dataFile: string;
5
- static getItem<T = unknown>(keyName: string, defaultValue?: T): T;
6
- static setItem(keyName: string, keyValue: unknown): boolean;
7
- static removeItem(keyName: string): boolean;
8
- static clear(): boolean;
9
- }
4
+ export interface Storage extends SharedStorage {}
5
+
6
+ export const Storage: typeof import("../../polyfill/Storage.d.ts").Storage;
10
7
  }
@@ -1,7 +1,8 @@
1
1
  /// <reference path="./modules/core.d.ts" />
2
2
  /// <reference path="./modules/fetch.d.ts" />
3
+ /// <reference path="./modules/Lodash.d.ts" />
3
4
  /// <reference path="./modules/polyfills.d.ts" />
5
+ /// <reference path="./modules/qs.d.ts" />
4
6
  /// <reference path="./modules/storage.d.ts" />
5
- /// <reference path="./modules/kv.d.ts" />
6
7
  /// <reference path="./modules/getStorage.d.ts" />
7
8
  /// <reference path="./modules/environment.d.ts" />
package/polyfill/KV.mjs DELETED
@@ -1,218 +0,0 @@
1
- import { $app } from "../lib/app.mjs";
2
- import { Lodash as _ } from "./Lodash.mjs";
3
- import { Storage } from "./Storage.mjs";
4
-
5
- /**
6
- * Cloudflare Workers KV 异步适配器。
7
- * Async adapter for Cloudflare Workers KV.
8
- *
9
- * 设计目标:
10
- * Design goal:
11
- * - 提供与 `Storage` 接近的异步接口
12
- * - Provide an async API close to `Storage`
13
- * - 在 Worker 中使用显式传入的 KV namespace binding
14
- * - Use an explicitly passed KV namespace binding in Workers
15
- * - 在非 Worker 平台回退到 `Storage`
16
- * - Fall back to `Storage` on non-Worker platforms
17
- *
18
- * 支持路径键:
19
- * Supports path key:
20
- * - `@root.path.to.value`
21
- *
22
- * @link https://developers.cloudflare.com/kv/get-started/#5-access-your-kv-namespace-from-your-worker
23
- * @link https://developers.cloudflare.com/kv/api/read-key-value-pairs/
24
- * @link https://developers.cloudflare.com/kv/api/write-key-value-pairs/
25
- * @link https://developers.cloudflare.com/kv/api/delete-key-value-pairs/
26
- * @link https://developers.cloudflare.com/kv/api/list-keys/
27
- */
28
- export class KV {
29
- /**
30
- * `@key.path` 解析正则。
31
- * Regex for `@key.path` parsing.
32
- *
33
- * @type {RegExp}
34
- */
35
- static #nameRegex = /^@(?<key>[^.]+)(?:\.(?<path>.*))?$/;
36
-
37
- /**
38
- * Cloudflare KV namespace 绑定。
39
- * Cloudflare KV namespace binding.
40
- *
41
- * @type {{ get(key: string): Promise<string|null>; put(key: string, value: string): Promise<void>; delete(key: string): Promise<void>; list?(options?: { prefix?: string; limit?: number; cursor?: string }): Promise<{ keys: { name: string; expiration?: number; metadata?: object }[]; list_complete: boolean; cursor: string }> } | undefined}
42
- */
43
- namespace;
44
-
45
- /**
46
- * 创建 KV 适配器实例。
47
- * Create a KV adapter instance.
48
- *
49
- * @param {{ get(key: string): Promise<string|null>; put(key: string, value: string): Promise<void>; delete(key: string): Promise<void>; list?(options?: { prefix?: string; limit?: number; cursor?: string }): Promise<{ keys: { name: string; expiration?: number; metadata?: object }[]; list_complete: boolean; cursor: string }> } | null | undefined} namespace KV namespace 绑定 / KV namespace binding.
50
- */
51
- constructor(namespace) {
52
- this.namespace = namespace ?? undefined;
53
- }
54
-
55
- /**
56
- * 读取存储值。
57
- * Read value from persistent storage.
58
- *
59
- * @param {string} keyName 键名或路径键 / Key or path key.
60
- * @param {*} [defaultValue=null] 默认值 / Default value when key is missing.
61
- * @returns {Promise<*>}
62
- */
63
- async getItem(keyName, defaultValue = null) {
64
- let keyValue = defaultValue;
65
- switch (keyName.startsWith("@")) {
66
- case true: {
67
- const { key, path } = keyName.match(KV.#nameRegex)?.groups ?? {};
68
- keyName = key;
69
- let value = await this.getItem(keyName, {});
70
- if (typeof value !== "object" || value === null) value = {};
71
- keyValue = _.get(value, path);
72
- keyValue = KV.#deserialize(keyValue);
73
- break;
74
- }
75
- default:
76
- switch ($app) {
77
- case "Worker":
78
- keyValue = await this.namespace.get(keyName);
79
- break;
80
- default:
81
- keyValue = Storage.getItem(keyName, defaultValue);
82
- break;
83
- }
84
- keyValue = KV.#deserialize(keyValue);
85
- break;
86
- }
87
- return keyValue ?? defaultValue;
88
- }
89
-
90
- /**
91
- * 写入存储值。
92
- * Write value into persistent storage.
93
- *
94
- * @param {string} keyName 键名或路径键 / Key or path key.
95
- * @param {*} keyValue 写入值 / Value to store.
96
- * @returns {Promise<boolean>}
97
- */
98
- async setItem(keyName = new String(), keyValue = new String()) {
99
- let result = false;
100
- keyValue = KV.#serialize(keyValue);
101
- switch (keyName.startsWith("@")) {
102
- case true: {
103
- const { key, path } = keyName.match(KV.#nameRegex)?.groups ?? {};
104
- keyName = key;
105
- let value = await this.getItem(keyName, {});
106
- if (typeof value !== "object" || value === null) value = {};
107
- _.set(value, path, keyValue);
108
- result = await this.setItem(keyName, value);
109
- break;
110
- }
111
- default:
112
- switch ($app) {
113
- case "Worker":
114
- await this.namespace.put(keyName, keyValue);
115
- result = true;
116
- break;
117
- default:
118
- result = Storage.setItem(keyName, keyValue);
119
- break;
120
- }
121
- break;
122
- }
123
- return result;
124
- }
125
-
126
- /**
127
- * 删除存储值。
128
- * Remove value from persistent storage.
129
- *
130
- * @param {string} keyName 键名或路径键 / Key or path key.
131
- * @returns {Promise<boolean>}
132
- */
133
- async removeItem(keyName) {
134
- let result = false;
135
- switch (keyName.startsWith("@")) {
136
- case true: {
137
- const { key, path } = keyName.match(KV.#nameRegex)?.groups ?? {};
138
- keyName = key;
139
- let value = await this.getItem(keyName);
140
- if (typeof value !== "object" || value === null) value = {};
141
- _.unset(value, path);
142
- result = await this.setItem(keyName, value);
143
- break;
144
- }
145
- default:
146
- switch ($app) {
147
- case "Worker":
148
- await this.namespace.delete(keyName);
149
- result = true;
150
- break;
151
- default:
152
- result = Storage.removeItem(keyName);
153
- break;
154
- }
155
- break;
156
- }
157
- return result;
158
- }
159
-
160
- /**
161
- * 清空存储。
162
- * Clear storage.
163
- *
164
- * @returns {Promise<boolean>}
165
- */
166
- async clear() {
167
- return false;
168
- }
169
-
170
- /**
171
- * 列出命名空间中的键。
172
- * List keys in the namespace.
173
- *
174
- * @param {{ prefix?: string; limit?: number; cursor?: string }} [options={}] 列举选项 / List options.
175
- * @returns {Promise<{ keys: { name: string; expiration?: number; metadata?: object }[]; list_complete: boolean; cursor: string }>}
176
- */
177
- async list(options = {}) {
178
- switch ($app) {
179
- case "Worker":
180
- return await this.namespace.list(options);
181
- default:
182
- throw new TypeError("KV.list() is only supported in Worker runtime.");
183
- }
184
- }
185
-
186
- /**
187
- * 尝试将字符串反序列化为原始值。
188
- * Try to deserialize a string into its original value.
189
- *
190
- * @private
191
- * @param {*} value 原始值 / Raw value.
192
- * @returns {*}
193
- */
194
- static #deserialize(value) {
195
- try {
196
- return JSON.parse(value);
197
- } catch (e) {
198
- return value;
199
- }
200
- }
201
-
202
- /**
203
- * 规范化待写入的值。
204
- * Normalize a value before persisting it.
205
- *
206
- * @private
207
- * @param {*} value 原始值 / Raw value.
208
- * @returns {string}
209
- */
210
- static #serialize(value) {
211
- switch (typeof value) {
212
- case "object":
213
- return JSON.stringify(value);
214
- default:
215
- return String(value);
216
- }
217
- }
218
- }
@@ -1,35 +0,0 @@
1
- declare module "@nsnanocat/util" {
2
- export interface KVNamespaceLike {
3
- get(key: string): Promise<string | null>;
4
- put(key: string, value: string): Promise<void>;
5
- delete(key: string): Promise<void>;
6
- list?(options?: KVListOptions): Promise<KVListResult>;
7
- }
8
-
9
- export interface KVListOptions {
10
- prefix?: string;
11
- limit?: number;
12
- cursor?: string;
13
- }
14
-
15
- export interface KVListKey {
16
- name: string;
17
- expiration?: number;
18
- metadata?: Record<string, unknown>;
19
- }
20
-
21
- export interface KVListResult {
22
- keys: KVListKey[];
23
- list_complete: boolean;
24
- cursor: string;
25
- }
26
-
27
- export class KV {
28
- constructor(namespace?: KVNamespaceLike | null);
29
- getItem<T = unknown>(keyName: string, defaultValue?: T): Promise<T>;
30
- setItem(keyName: string, keyValue: unknown): Promise<boolean>;
31
- removeItem(keyName: string): Promise<boolean>;
32
- clear(): Promise<boolean>;
33
- list(options?: KVListOptions): Promise<KVListResult>;
34
- }
35
- }