@jayfong/x-utils 1.0.0-202510061015 → 3.4.0
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/ai.d.mts +103 -0
- package/lib/ai.mjs +75 -0
- package/lib/cache.d.mts +464 -0
- package/lib/cache.mjs +531 -0
- package/lib/captcha.d.mts +259 -0
- package/lib/captcha.mjs +174 -0
- package/lib/case.d.mts +184 -0
- package/lib/case.mjs +120 -0
- package/lib/chinese.d.mts +57 -0
- package/lib/chinese.mjs +79 -0
- package/lib/cli.d.mts +52 -0
- package/lib/cli.mjs +62 -0
- package/lib/clipboard.d.mts +50 -0
- package/lib/clipboard.mjs +122 -0
- package/lib/cmd.d.mts +38 -0
- package/lib/cmd.mjs +52 -0
- package/lib/crawler.d.mts +330 -0
- package/lib/crawler.mjs +313 -0
- package/lib/crypto.d.mts +158 -0
- package/lib/crypto.mjs +213 -0
- package/lib/csv.d.mts +67 -0
- package/lib/csv.mjs +76 -0
- package/lib/data_set.d.mts +76 -0
- package/lib/data_set.mjs +104 -0
- package/lib/db_value.d.mts +213 -0
- package/lib/db_value.mjs +208 -0
- package/lib/dispose.d.mts +98 -0
- package/lib/dispose.mjs +107 -0
- package/lib/file_store.d.mts +167 -0
- package/lib/file_store.mjs +120 -0
- package/lib/fs.d.mts +111 -0
- package/lib/fs.mjs +127 -0
- package/lib/html.d.mts +103 -0
- package/lib/html.mjs +112 -0
- package/lib/json.d.mts +50 -0
- package/lib/json.mjs +74 -0
- package/lib/jwt.d.mts +128 -0
- package/lib/jwt.mjs +104 -0
- package/lib/mail.d.mts +125 -0
- package/lib/mail.mjs +108 -0
- package/lib/pay.d.mts +394 -0
- package/lib/pay.mjs +343 -0
- package/lib/puppeteer.d.mts +88 -0
- package/lib/puppeteer.mjs +219 -0
- package/lib/random.d.mts +71 -0
- package/lib/random.mjs +92 -0
- package/lib/redis.d.mts +32 -0
- package/lib/redis.mjs +24 -0
- package/lib/runner.d.mts +80 -0
- package/lib/runner.mjs +66 -0
- package/lib/sensitive_words.d.mts +82 -0
- package/lib/sensitive_words.mjs +73 -0
- package/lib/sms.d.mts +133 -0
- package/lib/sms.mjs +100 -0
- package/lib/task.d.mts +37 -0
- package/lib/task.mjs +43 -0
- package/lib/text.d.mts +84 -0
- package/lib/text.mjs +141 -0
- package/lib/yaml.d.mts +51 -0
- package/lib/yaml.mjs +64 -0
- package/package.json +82 -164
- package/_cjs/ai.js +0 -80
- package/_cjs/alipan.js +0 -173
- package/_cjs/cli.js +0 -51
- package/_cjs/clipboard.js +0 -65
- package/_cjs/cmd.js +0 -42
- package/_cjs/compressor.js +0 -47
- package/_cjs/crawler.js +0 -341
- package/_cjs/csv.js +0 -97
- package/_cjs/data_set.js +0 -115
- package/_cjs/env.js +0 -82
- package/_cjs/fs.js +0 -86
- package/_cjs/html.js +0 -62
- package/_cjs/http_server.js +0 -79
- package/_cjs/json.js +0 -49
- package/_cjs/ksb.js +0 -218
- package/_cjs/number.js +0 -39
- package/_cjs/ocr.js +0 -74
- package/_cjs/package.json +0 -3
- package/_cjs/path.js +0 -35
- package/_cjs/pinyin.js +0 -37
- package/_cjs/puppeteer.js +0 -271
- package/_cjs/runner.js +0 -88
- package/_cjs/task.js +0 -41
- package/_cjs/text.js +0 -136
- package/_cjs/unicode/lib_unicode.js +0 -58643
- package/_cjs/unicode/unicode.js +0 -441
- package/_cjs/upload.js +0 -101
- package/_cjs/yaml.js +0 -52
- package/ai.d.ts +0 -26
- package/ai.js +0 -60
- package/alipan.d.ts +0 -209
- package/alipan.js +0 -153
- package/cli.d.ts +0 -14
- package/cli.js +0 -21
- package/clipboard.d.ts +0 -6
- package/clipboard.js +0 -35
- package/cmd.d.ts +0 -5
- package/cmd.js +0 -22
- package/compressor.d.ts +0 -5
- package/compressor.js +0 -17
- package/crawler.d.ts +0 -162
- package/crawler.js +0 -332
- package/csv.d.ts +0 -14
- package/csv.js +0 -67
- package/data_set.d.ts +0 -22
- package/data_set.js +0 -85
- package/env.d.ts +0 -6
- package/env.js +0 -52
- package/fs.d.ts +0 -23
- package/fs.js +0 -56
- package/html.d.ts +0 -7
- package/html.js +0 -45
- package/http_server.d.ts +0 -13
- package/http_server.js +0 -49
- package/json.d.ts +0 -6
- package/json.js +0 -19
- package/ksb.d.ts +0 -37
- package/ksb.js +0 -198
- package/number.d.ts +0 -3
- package/number.js +0 -9
- package/ocr.d.ts +0 -17
- package/ocr.js +0 -54
- package/path.d.ts +0 -2
- package/path.js +0 -5
- package/pinyin.d.ts +0 -8
- package/pinyin.js +0 -17
- package/puppeteer.d.ts +0 -38
- package/puppeteer.js +0 -241
- package/runner.d.ts +0 -13
- package/runner.js +0 -58
- package/task.d.ts +0 -6
- package/task.js +0 -21
- package/text.d.ts +0 -63
- package/text.js +0 -119
- package/unicode/lib_unicode.d.ts +0 -4
- package/unicode/lib_unicode.js +0 -58623
- package/unicode/unicode.d.ts +0 -347
- package/unicode/unicode.js +0 -426
- package/upload.d.ts +0 -34
- package/upload.js +0 -71
- package/yaml.d.ts +0 -6
- package/yaml.js +0 -22
package/lib/sms.mjs
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import * as TencentCloud from "tencentcloud-sdk-nodejs-sms";
|
|
2
|
+
// src/sms.ts
|
|
3
|
+
/**
|
|
4
|
+
* 短信服务提供商。
|
|
5
|
+
*/
|
|
6
|
+
let SmsServiceProvider = /* @__PURE__ */ function(SmsServiceProvider) {
|
|
7
|
+
/** 腾讯云短信。 */
|
|
8
|
+
SmsServiceProvider["TencentCloud"] = "TencentCloud";
|
|
9
|
+
return SmsServiceProvider;
|
|
10
|
+
}({});
|
|
11
|
+
/**
|
|
12
|
+
* 短信发送工具。
|
|
13
|
+
*
|
|
14
|
+
* 统一封装各云厂商的短信发送接口,将厂商原始返回转换为统一的
|
|
15
|
+
* {@link XSmsSendResult}。当前支持腾讯云短信(
|
|
16
|
+
* {@link SmsServiceProvider.TencentCloud}),后续可在此基础上扩展更多
|
|
17
|
+
* 厂商。
|
|
18
|
+
*
|
|
19
|
+
* 腾讯云实现的几个关键点:
|
|
20
|
+
* 1. 使用 `tencentcloud-sdk-nodejs-sms` 的 `v20210111` 版本客户端;
|
|
21
|
+
* 2. 客户端构造必须显式传入 `region`(否则报错缺少 `Region` 参数),
|
|
22
|
+
* 短信用途下该值不参与实际路由,统一使用 `ap-beijing`;
|
|
23
|
+
* 3. 手机号规范化:以 `+` 开头视为 E.164 号码原样使用,否则自动补
|
|
24
|
+
* `+86` 前缀;
|
|
25
|
+
* 4. 单次发送一个号码,取返回的 `SendStatusSet[0]` 作为发送结果,
|
|
26
|
+
* `Code === 'Ok'` 视为成功;若服务商未返回任何状态则抛出错误。
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* const sms = new XSms({
|
|
30
|
+
* provider: SmsServiceProvider.TencentCloud,
|
|
31
|
+
* secretId: 'your-secret-id',
|
|
32
|
+
* secretKey: 'your-secret-key',
|
|
33
|
+
* appId: '1400000000',
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* const result = await sms.send({
|
|
37
|
+
* provider: SmsServiceProvider.TencentCloud,
|
|
38
|
+
* signature: '我的签名',
|
|
39
|
+
* templateId: '1234567',
|
|
40
|
+
* templateParamValues: ['123456', '5'],
|
|
41
|
+
* phoneNumber: '13800138000',
|
|
42
|
+
* });
|
|
43
|
+
* // result = { success: true, message: 'send success', smsId: '...' }
|
|
44
|
+
*/
|
|
45
|
+
var XSms = class {
|
|
46
|
+
options;
|
|
47
|
+
constructor(options) {
|
|
48
|
+
this.options = options;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 发送短信。
|
|
52
|
+
*
|
|
53
|
+
* 根据 `payload.provider` 路由到对应厂商:
|
|
54
|
+
* - {@link SmsServiceProvider.TencentCloud}:创建腾讯云短信客户端并调用
|
|
55
|
+
* `SendSms`,将返回的首条发送状态映射为 {@link XSmsSendResult};
|
|
56
|
+
* - 其他未知提供商:抛出错误。
|
|
57
|
+
*
|
|
58
|
+
* 手机号规范化:以 `+` 开头视为 E.164 号码原样使用,否则自动补
|
|
59
|
+
* `+86` 前缀后发送(与腾讯云「境内号码默认 +86」的规则一致)。
|
|
60
|
+
*
|
|
61
|
+
* @param payload 发送参数,见 {@link XSmsSendPayload}。
|
|
62
|
+
* @returns 发送结果,见 {@link XSmsSendResult}。
|
|
63
|
+
* @throws 当提供商不受支持,或服务商未返回任何发送状态时抛出错误。
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* await sms.send({
|
|
67
|
+
* provider: SmsServiceProvider.TencentCloud,
|
|
68
|
+
* signature: '我的签名',
|
|
69
|
+
* templateId: '1234567',
|
|
70
|
+
* templateParamValues: ['123456'],
|
|
71
|
+
* phoneNumber: '13800138000',
|
|
72
|
+
* });
|
|
73
|
+
*/
|
|
74
|
+
async send(payload) {
|
|
75
|
+
if (payload.provider === "TencentCloud") {
|
|
76
|
+
const SmsClient = TencentCloud.sms.v20210111.Client;
|
|
77
|
+
const sendStatus = (await new SmsClient({
|
|
78
|
+
region: "ap-beijing",
|
|
79
|
+
credential: {
|
|
80
|
+
secretId: this.options.secretId,
|
|
81
|
+
secretKey: this.options.secretKey
|
|
82
|
+
}
|
|
83
|
+
}).SendSms({
|
|
84
|
+
SmsSdkAppId: this.options.appId,
|
|
85
|
+
SignName: payload.signature,
|
|
86
|
+
TemplateId: payload.templateId,
|
|
87
|
+
TemplateParamSet: payload.templateParamValues,
|
|
88
|
+
PhoneNumberSet: [payload.phoneNumber[0] === "+" ? payload.phoneNumber : `+86${payload.phoneNumber}`]
|
|
89
|
+
})).SendStatusSet?.[0];
|
|
90
|
+
if (!sendStatus) throw new Error("腾讯云短信发送失败:服务商未返回发送状态");
|
|
91
|
+
return {
|
|
92
|
+
success: sendStatus.Code === "Ok",
|
|
93
|
+
message: sendStatus.Message,
|
|
94
|
+
smsId: sendStatus.SerialNo
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
throw new Error(`no sms provider: ${payload.provider}`);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
export { SmsServiceProvider, XSms };
|
package/lib/task.d.mts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 可复用任务基类。
|
|
3
|
+
*
|
|
4
|
+
* 封装了进程退出时的资源清理与退出码处理:
|
|
5
|
+
* 1. `run()` 启动前注册退出钩子,进程退出时自动调用 `dispose()` 释放资源;
|
|
6
|
+
* 2. `start()` 成功后以退出码 `0` 优雅退出;
|
|
7
|
+
* 3. `start()` 失败时记录错误日志,并以退出码 `1` 优雅退出。
|
|
8
|
+
*
|
|
9
|
+
* 使用方式:
|
|
10
|
+
* - 继承并实现 `start()`,将任务主逻辑放入其中;
|
|
11
|
+
* - 可选地覆写 `dispose()` 以释放连接、文件句柄等资源。
|
|
12
|
+
*/
|
|
13
|
+
export declare abstract class XTask {
|
|
14
|
+
/** 日志实例,子类可直接通过 `this.log` 输出日志。 */
|
|
15
|
+
log: import("consola").ConsolaInstance;
|
|
16
|
+
/**
|
|
17
|
+
* 任务主入口,子类必须实现。
|
|
18
|
+
*
|
|
19
|
+
* 成功 resolve 视为任务成功;抛错(reject)则触发错误日志与失败退出码。
|
|
20
|
+
*/
|
|
21
|
+
abstract start(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* 进程退出前的资源清理钩子,默认无操作。
|
|
24
|
+
*
|
|
25
|
+
* 子类可覆写以释放数据库连接、临时文件等资源;退出钩子最多等待 3000ms。
|
|
26
|
+
*/
|
|
27
|
+
dispose(): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* 运行任务。
|
|
30
|
+
*
|
|
31
|
+
* 行为说明:
|
|
32
|
+
* 1. 注册退出钩子:进程退出时调用 `dispose()`,等待时长 3000ms;
|
|
33
|
+
* 2. 执行 `start()`,成功后以退出码 `0` 优雅退出;
|
|
34
|
+
* 3. 执行失败时记录错误并以退出码 `1` 优雅退出。
|
|
35
|
+
*/
|
|
36
|
+
run(): Promise<never>;
|
|
37
|
+
}
|
package/lib/task.mjs
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { XDispose } from "./dispose.mjs";
|
|
2
|
+
import { consola } from "consola";
|
|
3
|
+
// src/task.ts
|
|
4
|
+
/**
|
|
5
|
+
* 可复用任务基类。
|
|
6
|
+
*
|
|
7
|
+
* 封装了进程退出时的资源清理与退出码处理:
|
|
8
|
+
* 1. `run()` 启动前注册退出钩子,进程退出时自动调用 `dispose()` 释放资源;
|
|
9
|
+
* 2. `start()` 成功后以退出码 `0` 优雅退出;
|
|
10
|
+
* 3. `start()` 失败时记录错误日志,并以退出码 `1` 优雅退出。
|
|
11
|
+
*
|
|
12
|
+
* 使用方式:
|
|
13
|
+
* - 继承并实现 `start()`,将任务主逻辑放入其中;
|
|
14
|
+
* - 可选地覆写 `dispose()` 以释放连接、文件句柄等资源。
|
|
15
|
+
*/
|
|
16
|
+
var XTask = class {
|
|
17
|
+
/** 日志实例,子类可直接通过 `this.log` 输出日志。 */
|
|
18
|
+
log = consola;
|
|
19
|
+
/**
|
|
20
|
+
* 进程退出前的资源清理钩子,默认无操作。
|
|
21
|
+
*
|
|
22
|
+
* 子类可覆写以释放数据库连接、临时文件等资源;退出钩子最多等待 3000ms。
|
|
23
|
+
*/
|
|
24
|
+
async dispose() {}
|
|
25
|
+
/**
|
|
26
|
+
* 运行任务。
|
|
27
|
+
*
|
|
28
|
+
* 行为说明:
|
|
29
|
+
* 1. 注册退出钩子:进程退出时调用 `dispose()`,等待时长 3000ms;
|
|
30
|
+
* 2. 执行 `start()`,成功后以退出码 `0` 优雅退出;
|
|
31
|
+
* 3. 执行失败时记录错误并以退出码 `1` 优雅退出。
|
|
32
|
+
*/
|
|
33
|
+
run() {
|
|
34
|
+
XDispose.exit.add(() => this.dispose());
|
|
35
|
+
return this.start().then(() => {
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}).catch((err) => {
|
|
38
|
+
consola.error(err);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export { XTask };
|
package/lib/text.d.mts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export declare class XText {
|
|
2
|
+
private text;
|
|
3
|
+
/**
|
|
4
|
+
* 将字符串按“用户可见字符(grapheme)”分割为数组。
|
|
5
|
+
*
|
|
6
|
+
* 与 `text.split('')` 不同,这里会正确处理 Emoji、组合字符等场景,
|
|
7
|
+
* 例如 `👍🏽` 会被视为一个字符而不是多个 code unit。
|
|
8
|
+
*
|
|
9
|
+
* @see https://stackoverflow.com/a/71619350
|
|
10
|
+
*/
|
|
11
|
+
static split(text: string): string[];
|
|
12
|
+
/**
|
|
13
|
+
* HTML 模板字符串辅助函数。
|
|
14
|
+
*
|
|
15
|
+
* 该方法不做任何转义,仅用于让书写 HTML 片段时有模板字符串提示。
|
|
16
|
+
* 若插值来自不可信输入,应在调用前自行做转义/清洗。
|
|
17
|
+
*/
|
|
18
|
+
static html(literals: TemplateStringsArray, ...interpolations: unknown[]): string;
|
|
19
|
+
/**
|
|
20
|
+
* 提取 `start` 与 `end` 之间的内容。
|
|
21
|
+
*
|
|
22
|
+
* 规则:
|
|
23
|
+
* - 若 `start` 或 `end` 任一边界不存在,返回空字符串;
|
|
24
|
+
* - 仅提取从第一个 `start` 开始、到其后第一个 `end` 之前的内容;
|
|
25
|
+
* - 不包含边界本身。
|
|
26
|
+
*/
|
|
27
|
+
static cut(text: string, start: string, end: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* 移除全部空白字符(含空格、换行、制表符等)。
|
|
30
|
+
*/
|
|
31
|
+
static stripWhitespace(text: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* 移除首尾空白字符,保留中间内容。
|
|
34
|
+
*/
|
|
35
|
+
static stripMarginWhitespace(text: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* HTML 实体编码。
|
|
38
|
+
*/
|
|
39
|
+
static encodeHtmlEntity(text: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* HTML 实体解码。
|
|
42
|
+
*/
|
|
43
|
+
static decodeHtmlEntity(text: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* 移除 HTML 标签内容,包含 `script/style` 标签块。
|
|
46
|
+
*
|
|
47
|
+
* 注意:
|
|
48
|
+
* - 该方法面向轻量文本清洗,不是完整的 HTML 解析器;
|
|
49
|
+
* - 对复杂畸形 HTML 不能保证 100% 精确。
|
|
50
|
+
*/
|
|
51
|
+
static stripHtml(text: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* 创建一个可链式处理的文本实例。
|
|
54
|
+
*/
|
|
55
|
+
constructor(text: string);
|
|
56
|
+
/**
|
|
57
|
+
* 链式版本:提取 `start` 与 `end` 之间的内容。
|
|
58
|
+
*/
|
|
59
|
+
cut(start: string, end: string): this;
|
|
60
|
+
/**
|
|
61
|
+
* 链式版本:移除全部空白字符。
|
|
62
|
+
*/
|
|
63
|
+
stripWhitespace(): this;
|
|
64
|
+
/**
|
|
65
|
+
* 链式版本:移除首尾空白字符。
|
|
66
|
+
*/
|
|
67
|
+
stripMarginWhitespace(): this;
|
|
68
|
+
/**
|
|
69
|
+
* 链式版本:HTML 实体编码。
|
|
70
|
+
*/
|
|
71
|
+
encodeHtmlEntity(): this;
|
|
72
|
+
/**
|
|
73
|
+
* 链式版本:HTML 实体解码。
|
|
74
|
+
*/
|
|
75
|
+
decodeHtmlEntity(): this;
|
|
76
|
+
/**
|
|
77
|
+
* 链式版本:移除 HTML 代码。
|
|
78
|
+
*/
|
|
79
|
+
stripHtml(): this;
|
|
80
|
+
/**
|
|
81
|
+
* 返回当前链式处理后的文本。
|
|
82
|
+
*/
|
|
83
|
+
toString(): string;
|
|
84
|
+
}
|
package/lib/text.mjs
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { decode, encode } from "html-entities";
|
|
2
|
+
// src/text.ts
|
|
3
|
+
var XText = class XText {
|
|
4
|
+
text;
|
|
5
|
+
/**
|
|
6
|
+
* 将字符串按“用户可见字符(grapheme)”分割为数组。
|
|
7
|
+
*
|
|
8
|
+
* 与 `text.split('')` 不同,这里会正确处理 Emoji、组合字符等场景,
|
|
9
|
+
* 例如 `👍🏽` 会被视为一个字符而不是多个 code unit。
|
|
10
|
+
*
|
|
11
|
+
* @see https://stackoverflow.com/a/71619350
|
|
12
|
+
*/
|
|
13
|
+
static split(text) {
|
|
14
|
+
return [...new Intl.Segmenter().segment(text)].map((x) => x.segment);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* HTML 模板字符串辅助函数。
|
|
18
|
+
*
|
|
19
|
+
* 该方法不做任何转义,仅用于让书写 HTML 片段时有模板字符串提示。
|
|
20
|
+
* 若插值来自不可信输入,应在调用前自行做转义/清洗。
|
|
21
|
+
*/
|
|
22
|
+
static html(literals, ...interpolations) {
|
|
23
|
+
let result = "";
|
|
24
|
+
for (let i = 0; i < interpolations.length; i++) {
|
|
25
|
+
result += literals[i];
|
|
26
|
+
result += interpolations[i];
|
|
27
|
+
}
|
|
28
|
+
result += literals[literals.length - 1];
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 提取 `start` 与 `end` 之间的内容。
|
|
33
|
+
*
|
|
34
|
+
* 规则:
|
|
35
|
+
* - 若 `start` 或 `end` 任一边界不存在,返回空字符串;
|
|
36
|
+
* - 仅提取从第一个 `start` 开始、到其后第一个 `end` 之前的内容;
|
|
37
|
+
* - 不包含边界本身。
|
|
38
|
+
*/
|
|
39
|
+
static cut(text, start, end) {
|
|
40
|
+
const startIndex = text.indexOf(start);
|
|
41
|
+
if (startIndex < 0) return "";
|
|
42
|
+
const contentStartIndex = startIndex + start.length;
|
|
43
|
+
const endIndex = text.indexOf(end, contentStartIndex);
|
|
44
|
+
if (endIndex < 0) return "";
|
|
45
|
+
return text.slice(contentStartIndex, endIndex);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 移除全部空白字符(含空格、换行、制表符等)。
|
|
49
|
+
*/
|
|
50
|
+
static stripWhitespace(text) {
|
|
51
|
+
text = text.replace(/\s+/g, "");
|
|
52
|
+
return text;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 移除首尾空白字符,保留中间内容。
|
|
56
|
+
*/
|
|
57
|
+
static stripMarginWhitespace(text) {
|
|
58
|
+
text = text.trim();
|
|
59
|
+
return text;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* HTML 实体编码。
|
|
63
|
+
*/
|
|
64
|
+
static encodeHtmlEntity(text) {
|
|
65
|
+
text = encode(text);
|
|
66
|
+
return text;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* HTML 实体解码。
|
|
70
|
+
*/
|
|
71
|
+
static decodeHtmlEntity(text) {
|
|
72
|
+
text = decode(text);
|
|
73
|
+
return text;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 移除 HTML 标签内容,包含 `script/style` 标签块。
|
|
77
|
+
*
|
|
78
|
+
* 注意:
|
|
79
|
+
* - 该方法面向轻量文本清洗,不是完整的 HTML 解析器;
|
|
80
|
+
* - 对复杂畸形 HTML 不能保证 100% 精确。
|
|
81
|
+
*/
|
|
82
|
+
static stripHtml(text) {
|
|
83
|
+
text = text.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, "").replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, "").replace(/<\/?[^>]+>/g, "");
|
|
84
|
+
return text;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* 创建一个可链式处理的文本实例。
|
|
88
|
+
*/
|
|
89
|
+
constructor(text) {
|
|
90
|
+
this.text = text;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 链式版本:提取 `start` 与 `end` 之间的内容。
|
|
94
|
+
*/
|
|
95
|
+
cut(start, end) {
|
|
96
|
+
this.text = XText.cut(this.text, start, end);
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 链式版本:移除全部空白字符。
|
|
101
|
+
*/
|
|
102
|
+
stripWhitespace() {
|
|
103
|
+
this.text = XText.stripWhitespace(this.text);
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 链式版本:移除首尾空白字符。
|
|
108
|
+
*/
|
|
109
|
+
stripMarginWhitespace() {
|
|
110
|
+
this.text = XText.stripMarginWhitespace(this.text);
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 链式版本:HTML 实体编码。
|
|
115
|
+
*/
|
|
116
|
+
encodeHtmlEntity() {
|
|
117
|
+
this.text = XText.encodeHtmlEntity(this.text);
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 链式版本:HTML 实体解码。
|
|
122
|
+
*/
|
|
123
|
+
decodeHtmlEntity() {
|
|
124
|
+
this.text = XText.decodeHtmlEntity(this.text);
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* 链式版本:移除 HTML 代码。
|
|
129
|
+
*/
|
|
130
|
+
stripHtml() {
|
|
131
|
+
this.text = XText.stripHtml(this.text);
|
|
132
|
+
return this;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* 返回当前链式处理后的文本。
|
|
136
|
+
*/
|
|
137
|
+
toString() {
|
|
138
|
+
return this.text;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
export { XText };
|
package/lib/yaml.d.mts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 封装常用 YAML 文本处理逻辑,统一提供解析、序列化、文件读写入口。
|
|
3
|
+
*
|
|
4
|
+
* 设计目标:
|
|
5
|
+
* - 让调用方无需直接接触 `yaml` 依赖细节;
|
|
6
|
+
* - 统一使用 UTF-8 文本读取/写入;
|
|
7
|
+
* - 通过 `blockQuote: 'literal'` 保持多行文本块更稳定的输出格式,避免
|
|
8
|
+
* 长文本在 YAML 中被错误地折叠或渲染为普通单行字符串。
|
|
9
|
+
*
|
|
10
|
+
* 典型用法:
|
|
11
|
+
* - `const cfg = XYaml.parse<{ name: string }>(content)`
|
|
12
|
+
* - `await XYaml.write('/tmp/app.yaml', { name: 'demo' })`
|
|
13
|
+
*/
|
|
14
|
+
export declare class XYaml {
|
|
15
|
+
/**
|
|
16
|
+
* 解析 YAML 文本为目标类型。
|
|
17
|
+
*
|
|
18
|
+
* 适用场景包括配置文件、表单内容、轻量结构化描述等。由于 YAML 语法
|
|
19
|
+
* 允许解析为对象、数组、布尔值、数字、字符串等原始值,因此这里使用
|
|
20
|
+
* 泛型让调用方在类型层面明确期望值。
|
|
21
|
+
*
|
|
22
|
+
* 例子:
|
|
23
|
+
* ```ts
|
|
24
|
+
* const config = XYaml.parse<{ name: string; port: number }>(`\nname: demo\nport: 3000\n`);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
static parse<T>(value: string): T;
|
|
28
|
+
/**
|
|
29
|
+
* 将任意值转换成 YAML 文本。
|
|
30
|
+
*
|
|
31
|
+
* 这里固定使用 `blockQuote: 'literal'`,这样当值中包含多行字符串时,
|
|
32
|
+
* 输出会优先采用 `|` 形式的 literal block,与普通单行折叠输出相比更
|
|
33
|
+
* 稳定,也更符合配置文件/说明文档场景的阅读习惯。
|
|
34
|
+
*/
|
|
35
|
+
static stringify(value: unknown): string;
|
|
36
|
+
/**
|
|
37
|
+
* 读取 YAML 文件并立即解析为指定类型。
|
|
38
|
+
*
|
|
39
|
+
* 读取时使用 UTF-8 编码,适合配置文件、模板文件或脚本状态容器。若
|
|
40
|
+
* 文件为空,`yaml.parse` 可能返回 `null`,调用方需要按业务规则处理。
|
|
41
|
+
*/
|
|
42
|
+
static read<T>(file: string): Promise<T>;
|
|
43
|
+
/**
|
|
44
|
+
* 将对象写入 YAML 文件。
|
|
45
|
+
*
|
|
46
|
+
* 这里不额外指定缩进或换行策略,使用 `stringify` 的统一默认行为;
|
|
47
|
+
* 一旦调用方传入 `undefined`,`yaml.stringify` 会输出空文档,调用方应在
|
|
48
|
+
* 业务层避免该情况,或在必要时进行显式校验。
|
|
49
|
+
*/
|
|
50
|
+
static write(file: string, value: unknown): Promise<void>;
|
|
51
|
+
}
|
package/lib/yaml.mjs
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import yaml from "yaml";
|
|
3
|
+
// src/yaml.ts
|
|
4
|
+
/**
|
|
5
|
+
* 封装常用 YAML 文本处理逻辑,统一提供解析、序列化、文件读写入口。
|
|
6
|
+
*
|
|
7
|
+
* 设计目标:
|
|
8
|
+
* - 让调用方无需直接接触 `yaml` 依赖细节;
|
|
9
|
+
* - 统一使用 UTF-8 文本读取/写入;
|
|
10
|
+
* - 通过 `blockQuote: 'literal'` 保持多行文本块更稳定的输出格式,避免
|
|
11
|
+
* 长文本在 YAML 中被错误地折叠或渲染为普通单行字符串。
|
|
12
|
+
*
|
|
13
|
+
* 典型用法:
|
|
14
|
+
* - `const cfg = XYaml.parse<{ name: string }>(content)`
|
|
15
|
+
* - `await XYaml.write('/tmp/app.yaml', { name: 'demo' })`
|
|
16
|
+
*/
|
|
17
|
+
var XYaml = class XYaml {
|
|
18
|
+
/**
|
|
19
|
+
* 解析 YAML 文本为目标类型。
|
|
20
|
+
*
|
|
21
|
+
* 适用场景包括配置文件、表单内容、轻量结构化描述等。由于 YAML 语法
|
|
22
|
+
* 允许解析为对象、数组、布尔值、数字、字符串等原始值,因此这里使用
|
|
23
|
+
* 泛型让调用方在类型层面明确期望值。
|
|
24
|
+
*
|
|
25
|
+
* 例子:
|
|
26
|
+
* ```ts
|
|
27
|
+
* const config = XYaml.parse<{ name: string; port: number }>(`\nname: demo\nport: 3000\n`);
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
static parse(value) {
|
|
31
|
+
return yaml.parse(value);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 将任意值转换成 YAML 文本。
|
|
35
|
+
*
|
|
36
|
+
* 这里固定使用 `blockQuote: 'literal'`,这样当值中包含多行字符串时,
|
|
37
|
+
* 输出会优先采用 `|` 形式的 literal block,与普通单行折叠输出相比更
|
|
38
|
+
* 稳定,也更符合配置文件/说明文档场景的阅读习惯。
|
|
39
|
+
*/
|
|
40
|
+
static stringify(value) {
|
|
41
|
+
return yaml.stringify(value, { blockQuote: "literal" });
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 读取 YAML 文件并立即解析为指定类型。
|
|
45
|
+
*
|
|
46
|
+
* 读取时使用 UTF-8 编码,适合配置文件、模板文件或脚本状态容器。若
|
|
47
|
+
* 文件为空,`yaml.parse` 可能返回 `null`,调用方需要按业务规则处理。
|
|
48
|
+
*/
|
|
49
|
+
static async read(file) {
|
|
50
|
+
const value = await fs.promises.readFile(file, "utf8");
|
|
51
|
+
return XYaml.parse(value);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 将对象写入 YAML 文件。
|
|
55
|
+
*
|
|
56
|
+
* 这里不额外指定缩进或换行策略,使用 `stringify` 的统一默认行为;
|
|
57
|
+
* 一旦调用方传入 `undefined`,`yaml.stringify` 会输出空文档,调用方应在
|
|
58
|
+
* 业务层避免该情况,或在必要时进行显式校验。
|
|
59
|
+
*/
|
|
60
|
+
static async write(file, value) {
|
|
61
|
+
await fs.promises.writeFile(file, XYaml.stringify(value));
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
export { XYaml };
|