@jayfong/x-utils 1.0.0-202410181400 → 3.3.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/case.d.mts +184 -0
- package/lib/case.mjs +120 -0
- package/lib/chinese.d.mts +39 -0
- package/lib/chinese.mjs +52 -0
- package/lib/cli.d.mts +64 -0
- package/lib/cli.mjs +59 -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/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/fs.d.mts +49 -0
- package/lib/fs.mjs +65 -0
- package/lib/json.d.mts +50 -0
- package/lib/json.mjs +74 -0
- package/lib/puppeteer.d.mts +88 -0
- package/lib/puppeteer.mjs +219 -0
- package/lib/runner.d.mts +52 -0
- package/lib/runner.mjs +50 -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 +50 -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/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/case.d.mts
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { Options, PascalCaseOptions } from "change-case";
|
|
2
|
+
/**
|
|
3
|
+
* `XCase.camel` 的 options 参数。
|
|
4
|
+
*
|
|
5
|
+
* 继承自 `change-case` 的 `PascalCaseOptions`,支持
|
|
6
|
+
* `mergeAmbiguousCharacters` 等全部配置项,属性语义与默认行为
|
|
7
|
+
* 同 change-case,调用时原样透传。
|
|
8
|
+
*/
|
|
9
|
+
export interface XCaseCamelOptions extends PascalCaseOptions {}
|
|
10
|
+
/**
|
|
11
|
+
* `XCase.pascal` 的 options 参数。
|
|
12
|
+
*
|
|
13
|
+
* 继承自 `change-case` 的 `PascalCaseOptions`,支持
|
|
14
|
+
* `mergeAmbiguousCharacters` 等全部配置项,属性语义与默认行为
|
|
15
|
+
* 同 change-case,调用时原样透传。
|
|
16
|
+
*/
|
|
17
|
+
export interface XCasePascalOptions extends PascalCaseOptions {}
|
|
18
|
+
/**
|
|
19
|
+
* `XCase.pascalSnake` 的 options 参数。
|
|
20
|
+
*
|
|
21
|
+
* 继承自 `change-case` 的 `Options`,支持 `locale`、`delimiter`、
|
|
22
|
+
* `split` 等全部配置项,属性语义与默认行为同 change-case,
|
|
23
|
+
* 调用时原样透传。
|
|
24
|
+
*/
|
|
25
|
+
export interface XCasePascalSnakeOptions extends Options {}
|
|
26
|
+
/**
|
|
27
|
+
* `XCase.capital` 的 options 参数。
|
|
28
|
+
*
|
|
29
|
+
* 继承自 `change-case` 的 `Options`,支持 `locale`、`delimiter`、
|
|
30
|
+
* `split` 等全部配置项,属性语义与默认行为同 change-case,
|
|
31
|
+
* 调用时原样透传。
|
|
32
|
+
*/
|
|
33
|
+
export interface XCaseCapitalOptions extends Options {}
|
|
34
|
+
/**
|
|
35
|
+
* `XCase.constant` 的 options 参数。
|
|
36
|
+
*
|
|
37
|
+
* 继承自 `change-case` 的 `Options`,支持 `locale`、`delimiter`、
|
|
38
|
+
* `split` 等全部配置项,属性语义与默认行为同 change-case,
|
|
39
|
+
* 调用时原样透传。
|
|
40
|
+
*/
|
|
41
|
+
export interface XCaseConstantOptions extends Options {}
|
|
42
|
+
/**
|
|
43
|
+
* `XCase.dot` 的 options 参数。
|
|
44
|
+
*
|
|
45
|
+
* 继承自 `change-case` 的 `Options`,支持 `locale`、`delimiter`、
|
|
46
|
+
* `split` 等全部配置项,属性语义与默认行为同 change-case,
|
|
47
|
+
* 调用时原样透传。
|
|
48
|
+
*/
|
|
49
|
+
export interface XCaseDotOptions extends Options {}
|
|
50
|
+
/**
|
|
51
|
+
* `XCase.kebab` 的 options 参数。
|
|
52
|
+
*
|
|
53
|
+
* 继承自 `change-case` 的 `Options`,支持 `locale`、`delimiter`、
|
|
54
|
+
* `split` 等全部配置项,属性语义与默认行为同 change-case,
|
|
55
|
+
* 调用时原样透传。
|
|
56
|
+
*/
|
|
57
|
+
export interface XCaseKebabOptions extends Options {}
|
|
58
|
+
/**
|
|
59
|
+
* `XCase.path` 的 options 参数。
|
|
60
|
+
*
|
|
61
|
+
* 继承自 `change-case` 的 `Options`,支持 `locale`、`delimiter`、
|
|
62
|
+
* `split` 等全部配置项,属性语义与默认行为同 change-case,
|
|
63
|
+
* 调用时原样透传。
|
|
64
|
+
*/
|
|
65
|
+
export interface XCasePathOptions extends Options {}
|
|
66
|
+
/**
|
|
67
|
+
* `XCase.sentence` 的 options 参数。
|
|
68
|
+
*
|
|
69
|
+
* 继承自 `change-case` 的 `Options`,支持 `locale`、`delimiter`、
|
|
70
|
+
* `split` 等全部配置项,属性语义与默认行为同 change-case,
|
|
71
|
+
* 调用时原样透传。
|
|
72
|
+
*/
|
|
73
|
+
export interface XCaseSentenceOptions extends Options {}
|
|
74
|
+
/**
|
|
75
|
+
* `XCase.snake` 的 options 参数。
|
|
76
|
+
*
|
|
77
|
+
* 继承自 `change-case` 的 `Options`,支持 `locale`、`delimiter`、
|
|
78
|
+
* `split` 等全部配置项,属性语义与默认行为同 change-case,
|
|
79
|
+
* 调用时原样透传。
|
|
80
|
+
*/
|
|
81
|
+
export interface XCaseSnakeOptions extends Options {}
|
|
82
|
+
/**
|
|
83
|
+
* `XCase.train` 的 options 参数。
|
|
84
|
+
*
|
|
85
|
+
* 继承自 `change-case` 的 `Options`,支持 `locale`、`delimiter`、
|
|
86
|
+
* `split` 等全部配置项,属性语义与默认行为同 change-case,
|
|
87
|
+
* 调用时原样透传。
|
|
88
|
+
*/
|
|
89
|
+
export interface XCaseTrainOptions extends Options {}
|
|
90
|
+
/**
|
|
91
|
+
* 字符串大小写风格转换工具。
|
|
92
|
+
*
|
|
93
|
+
* 所有方法均委托给 `change-case` 包实现,方法名去掉了原函数名的 `Case`
|
|
94
|
+
* 后缀(如 `camelCase` → `camel`,`pascalSnakeCase` → `pascalSnake`)。
|
|
95
|
+
*
|
|
96
|
+
* 各方法的 `options` 参数会原样透传给 `change-case` 对应函数,
|
|
97
|
+
* 类型分别为导出的 `XCaseCamelOptions`、`XCasePascalOptions`、
|
|
98
|
+
* `XCasePascalSnakeOptions`、`XCaseCapitalOptions`、`XCaseConstantOptions`、
|
|
99
|
+
* `XCaseDotOptions`、`XCaseKebabOptions`、`XCasePathOptions`、
|
|
100
|
+
* `XCaseSentenceOptions`、`XCaseSnakeOptions`、`XCaseTrainOptions`,
|
|
101
|
+
* 可配置 `locale`、`delimiter`、`split` 等(`camel`/`pascal` 额外支持
|
|
102
|
+
* `mergeAmbiguousCharacters`)。
|
|
103
|
+
*
|
|
104
|
+
* 以 `Hello World` 为例,各方法的输出:
|
|
105
|
+
* - `camel` → `helloWorld`
|
|
106
|
+
* - `pascal` → `HelloWorld`
|
|
107
|
+
* - `pascalSnake` → `Hello_World`
|
|
108
|
+
* - `capital` → `Hello World`
|
|
109
|
+
* - `constant` → `HELLO_WORLD`
|
|
110
|
+
* - `dot` → `hello.world`
|
|
111
|
+
* - `kebab` → `hello-world`
|
|
112
|
+
* - `path` → `hello/world`
|
|
113
|
+
* - `sentence` → `Hello world`
|
|
114
|
+
* - `snake` → `hello_world`
|
|
115
|
+
* - `train` → `Hello-World`
|
|
116
|
+
*/
|
|
117
|
+
export declare class XCase {
|
|
118
|
+
/**
|
|
119
|
+
* 转换为 camelCase(小驼峰)命名。
|
|
120
|
+
*
|
|
121
|
+
* @example XCase.camel('Hello World') // 'helloWorld'
|
|
122
|
+
*/
|
|
123
|
+
static camel(text: string, options?: XCaseCamelOptions): string;
|
|
124
|
+
/**
|
|
125
|
+
* 转换为 PascalCase(大驼峰)命名。
|
|
126
|
+
*
|
|
127
|
+
* @example XCase.pascal('hello world') // 'HelloWorld'
|
|
128
|
+
*/
|
|
129
|
+
static pascal(text: string, options?: XCasePascalOptions): string;
|
|
130
|
+
/**
|
|
131
|
+
* 转换为 Pascal_Snake_Case(大驼峰 + 下划线)命名。
|
|
132
|
+
*
|
|
133
|
+
* @example XCase.pascalSnake('hello world') // 'Hello_World'
|
|
134
|
+
*/
|
|
135
|
+
static pascalSnake(text: string, options?: XCasePascalSnakeOptions): string;
|
|
136
|
+
/**
|
|
137
|
+
* 转换为 Capital Case(首字母大写的空格分隔)命名。
|
|
138
|
+
*
|
|
139
|
+
* @example XCase.capital('hello world') // 'Hello World'
|
|
140
|
+
*/
|
|
141
|
+
static capital(text: string, options?: XCaseCapitalOptions): string;
|
|
142
|
+
/**
|
|
143
|
+
* 转换为 CONSTANT_CASE(全大写下划线)命名。
|
|
144
|
+
*
|
|
145
|
+
* @example XCase.constant('hello world') // 'HELLO_WORLD'
|
|
146
|
+
*/
|
|
147
|
+
static constant(text: string, options?: XCaseConstantOptions): string;
|
|
148
|
+
/**
|
|
149
|
+
* 转换为 dot.case(点号分隔)命名。
|
|
150
|
+
*
|
|
151
|
+
* @example XCase.dot('hello world') // 'hello.world'
|
|
152
|
+
*/
|
|
153
|
+
static dot(text: string, options?: XCaseDotOptions): string;
|
|
154
|
+
/**
|
|
155
|
+
* 转换为 kebab-case(短横线分隔)命名。
|
|
156
|
+
*
|
|
157
|
+
* @example XCase.kebab('Hello World') // 'hello-world'
|
|
158
|
+
*/
|
|
159
|
+
static kebab(text: string, options?: XCaseKebabOptions): string;
|
|
160
|
+
/**
|
|
161
|
+
* 转换为 path/case(斜杠分隔)命名。
|
|
162
|
+
*
|
|
163
|
+
* @example XCase.path('hello world') // 'hello/world'
|
|
164
|
+
*/
|
|
165
|
+
static path(text: string, options?: XCasePathOptions): string;
|
|
166
|
+
/**
|
|
167
|
+
* 转换为 Sentence case(首字母大写的句子)命名。
|
|
168
|
+
*
|
|
169
|
+
* @example XCase.sentence('hello world') // 'Hello world'
|
|
170
|
+
*/
|
|
171
|
+
static sentence(text: string, options?: XCaseSentenceOptions): string;
|
|
172
|
+
/**
|
|
173
|
+
* 转换为 snake_case(小写下划线)命名。
|
|
174
|
+
*
|
|
175
|
+
* @example XCase.snake('Hello World') // 'hello_world'
|
|
176
|
+
*/
|
|
177
|
+
static snake(text: string, options?: XCaseSnakeOptions): string;
|
|
178
|
+
/**
|
|
179
|
+
* 转换为 Train-Case(短横线分隔、各单词首字母大写)命名。
|
|
180
|
+
*
|
|
181
|
+
* @example XCase.train('hello world') // 'Hello-World'
|
|
182
|
+
*/
|
|
183
|
+
static train(text: string, options?: XCaseTrainOptions): string;
|
|
184
|
+
}
|
package/lib/case.mjs
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { camelCase, capitalCase, constantCase, dotCase, kebabCase, pascalCase, pascalSnakeCase, pathCase, sentenceCase, snakeCase, trainCase } from "change-case";
|
|
2
|
+
// src/case.ts
|
|
3
|
+
/**
|
|
4
|
+
* 字符串大小写风格转换工具。
|
|
5
|
+
*
|
|
6
|
+
* 所有方法均委托给 `change-case` 包实现,方法名去掉了原函数名的 `Case`
|
|
7
|
+
* 后缀(如 `camelCase` → `camel`,`pascalSnakeCase` → `pascalSnake`)。
|
|
8
|
+
*
|
|
9
|
+
* 各方法的 `options` 参数会原样透传给 `change-case` 对应函数,
|
|
10
|
+
* 类型分别为导出的 `XCaseCamelOptions`、`XCasePascalOptions`、
|
|
11
|
+
* `XCasePascalSnakeOptions`、`XCaseCapitalOptions`、`XCaseConstantOptions`、
|
|
12
|
+
* `XCaseDotOptions`、`XCaseKebabOptions`、`XCasePathOptions`、
|
|
13
|
+
* `XCaseSentenceOptions`、`XCaseSnakeOptions`、`XCaseTrainOptions`,
|
|
14
|
+
* 可配置 `locale`、`delimiter`、`split` 等(`camel`/`pascal` 额外支持
|
|
15
|
+
* `mergeAmbiguousCharacters`)。
|
|
16
|
+
*
|
|
17
|
+
* 以 `Hello World` 为例,各方法的输出:
|
|
18
|
+
* - `camel` → `helloWorld`
|
|
19
|
+
* - `pascal` → `HelloWorld`
|
|
20
|
+
* - `pascalSnake` → `Hello_World`
|
|
21
|
+
* - `capital` → `Hello World`
|
|
22
|
+
* - `constant` → `HELLO_WORLD`
|
|
23
|
+
* - `dot` → `hello.world`
|
|
24
|
+
* - `kebab` → `hello-world`
|
|
25
|
+
* - `path` → `hello/world`
|
|
26
|
+
* - `sentence` → `Hello world`
|
|
27
|
+
* - `snake` → `hello_world`
|
|
28
|
+
* - `train` → `Hello-World`
|
|
29
|
+
*/
|
|
30
|
+
var XCase = class {
|
|
31
|
+
/**
|
|
32
|
+
* 转换为 camelCase(小驼峰)命名。
|
|
33
|
+
*
|
|
34
|
+
* @example XCase.camel('Hello World') // 'helloWorld'
|
|
35
|
+
*/
|
|
36
|
+
static camel(text, options) {
|
|
37
|
+
return camelCase(text, options);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 转换为 PascalCase(大驼峰)命名。
|
|
41
|
+
*
|
|
42
|
+
* @example XCase.pascal('hello world') // 'HelloWorld'
|
|
43
|
+
*/
|
|
44
|
+
static pascal(text, options) {
|
|
45
|
+
return pascalCase(text, options);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 转换为 Pascal_Snake_Case(大驼峰 + 下划线)命名。
|
|
49
|
+
*
|
|
50
|
+
* @example XCase.pascalSnake('hello world') // 'Hello_World'
|
|
51
|
+
*/
|
|
52
|
+
static pascalSnake(text, options) {
|
|
53
|
+
return pascalSnakeCase(text, options);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 转换为 Capital Case(首字母大写的空格分隔)命名。
|
|
57
|
+
*
|
|
58
|
+
* @example XCase.capital('hello world') // 'Hello World'
|
|
59
|
+
*/
|
|
60
|
+
static capital(text, options) {
|
|
61
|
+
return capitalCase(text, options);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 转换为 CONSTANT_CASE(全大写下划线)命名。
|
|
65
|
+
*
|
|
66
|
+
* @example XCase.constant('hello world') // 'HELLO_WORLD'
|
|
67
|
+
*/
|
|
68
|
+
static constant(text, options) {
|
|
69
|
+
return constantCase(text, options);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 转换为 dot.case(点号分隔)命名。
|
|
73
|
+
*
|
|
74
|
+
* @example XCase.dot('hello world') // 'hello.world'
|
|
75
|
+
*/
|
|
76
|
+
static dot(text, options) {
|
|
77
|
+
return dotCase(text, options);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* 转换为 kebab-case(短横线分隔)命名。
|
|
81
|
+
*
|
|
82
|
+
* @example XCase.kebab('Hello World') // 'hello-world'
|
|
83
|
+
*/
|
|
84
|
+
static kebab(text, options) {
|
|
85
|
+
return kebabCase(text, options);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* 转换为 path/case(斜杠分隔)命名。
|
|
89
|
+
*
|
|
90
|
+
* @example XCase.path('hello world') // 'hello/world'
|
|
91
|
+
*/
|
|
92
|
+
static path(text, options) {
|
|
93
|
+
return pathCase(text, options);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* 转换为 Sentence case(首字母大写的句子)命名。
|
|
97
|
+
*
|
|
98
|
+
* @example XCase.sentence('hello world') // 'Hello world'
|
|
99
|
+
*/
|
|
100
|
+
static sentence(text, options) {
|
|
101
|
+
return sentenceCase(text, options);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 转换为 snake_case(小写下划线)命名。
|
|
105
|
+
*
|
|
106
|
+
* @example XCase.snake('Hello World') // 'hello_world'
|
|
107
|
+
*/
|
|
108
|
+
static snake(text, options) {
|
|
109
|
+
return snakeCase(text, options);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 转换为 Train-Case(短横线分隔、各单词首字母大写)命名。
|
|
113
|
+
*
|
|
114
|
+
* @example XCase.train('hello world') // 'Hello-World'
|
|
115
|
+
*/
|
|
116
|
+
static train(text, options) {
|
|
117
|
+
return trainCase(text, options);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
export { XCase };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 中文拼音转换工具。
|
|
3
|
+
*
|
|
4
|
+
* 基于 `pinyin-pro` 实现,返回逐字的拼音数组:
|
|
5
|
+
* - `pinyin`:无声调拼音,如 `XChinese.pinyin('我们')` → `['wo', 'men']`;
|
|
6
|
+
* - `pinyinWithTone`:带声调拼音(声调标在韵母上),
|
|
7
|
+
* 如 `XChinese.pinyinWithTone('我们')` → `['wǒ', 'men']`。
|
|
8
|
+
*
|
|
9
|
+
* 处理规则:
|
|
10
|
+
* - 每个汉字对应数组中的一个拼音元素;
|
|
11
|
+
* - 非汉字字符(字母、数字、符号、空白等)原样保留在结果中;
|
|
12
|
+
* - 多音字按 `pinyin-pro` 默认的逆向最大匹配分词规则取常用读音;
|
|
13
|
+
* - 空字符串返回空数组 `[]`。
|
|
14
|
+
*/
|
|
15
|
+
export declare class XChinese {
|
|
16
|
+
/**
|
|
17
|
+
* 获取无声调拼音。
|
|
18
|
+
*
|
|
19
|
+
* @param text 要转换的汉语字符串,可混含非汉字字符。
|
|
20
|
+
* @returns 拼音字符串数组,每个汉字对应一个元素,非汉字原样保留。
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* XChinese.pinyin('我们') // ['wo', 'men']
|
|
24
|
+
* XChinese.pinyin('我爱你') // ['wo', 'ai', 'ni']
|
|
25
|
+
* XChinese.pinyin('我爱ABC') // ['wo', 'ai', 'A', 'B', 'C']
|
|
26
|
+
*/
|
|
27
|
+
static pinyin(text: string): string[];
|
|
28
|
+
/**
|
|
29
|
+
* 获取带声调拼音(声调标在韵母上,如 `wǒ`、`ài`、`nǐ`)。
|
|
30
|
+
*
|
|
31
|
+
* @param text 要转换的汉语字符串,可混含非汉字字符。
|
|
32
|
+
* @returns 拼音字符串数组,每个汉字对应一个带声调元素,非汉字原样保留。
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* XChinese.pinyinWithTone('我们') // ['wǒ', 'men']
|
|
36
|
+
* XChinese.pinyinWithTone('我爱你') // ['wǒ', 'ài', 'nǐ']
|
|
37
|
+
*/
|
|
38
|
+
static pinyinWithTone(text: string): string[];
|
|
39
|
+
}
|
package/lib/chinese.mjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { pinyin } from "pinyin-pro";
|
|
2
|
+
// src/chinese.ts
|
|
3
|
+
/**
|
|
4
|
+
* 中文拼音转换工具。
|
|
5
|
+
*
|
|
6
|
+
* 基于 `pinyin-pro` 实现,返回逐字的拼音数组:
|
|
7
|
+
* - `pinyin`:无声调拼音,如 `XChinese.pinyin('我们')` → `['wo', 'men']`;
|
|
8
|
+
* - `pinyinWithTone`:带声调拼音(声调标在韵母上),
|
|
9
|
+
* 如 `XChinese.pinyinWithTone('我们')` → `['wǒ', 'men']`。
|
|
10
|
+
*
|
|
11
|
+
* 处理规则:
|
|
12
|
+
* - 每个汉字对应数组中的一个拼音元素;
|
|
13
|
+
* - 非汉字字符(字母、数字、符号、空白等)原样保留在结果中;
|
|
14
|
+
* - 多音字按 `pinyin-pro` 默认的逆向最大匹配分词规则取常用读音;
|
|
15
|
+
* - 空字符串返回空数组 `[]`。
|
|
16
|
+
*/
|
|
17
|
+
var XChinese = class {
|
|
18
|
+
/**
|
|
19
|
+
* 获取无声调拼音。
|
|
20
|
+
*
|
|
21
|
+
* @param text 要转换的汉语字符串,可混含非汉字字符。
|
|
22
|
+
* @returns 拼音字符串数组,每个汉字对应一个元素,非汉字原样保留。
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* XChinese.pinyin('我们') // ['wo', 'men']
|
|
26
|
+
* XChinese.pinyin('我爱你') // ['wo', 'ai', 'ni']
|
|
27
|
+
* XChinese.pinyin('我爱ABC') // ['wo', 'ai', 'A', 'B', 'C']
|
|
28
|
+
*/
|
|
29
|
+
static pinyin(text) {
|
|
30
|
+
return pinyin(text, {
|
|
31
|
+
type: "array",
|
|
32
|
+
toneType: "none"
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 获取带声调拼音(声调标在韵母上,如 `wǒ`、`ài`、`nǐ`)。
|
|
37
|
+
*
|
|
38
|
+
* @param text 要转换的汉语字符串,可混含非汉字字符。
|
|
39
|
+
* @returns 拼音字符串数组,每个汉字对应一个带声调元素,非汉字原样保留。
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* XChinese.pinyinWithTone('我们') // ['wǒ', 'men']
|
|
43
|
+
* XChinese.pinyinWithTone('我爱你') // ['wǒ', 'ài', 'nǐ']
|
|
44
|
+
*/
|
|
45
|
+
static pinyinWithTone(text) {
|
|
46
|
+
return pinyin(text, {
|
|
47
|
+
type: "array",
|
|
48
|
+
toneType: "symbol"
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
export { XChinese };
|
package/lib/cli.d.mts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 支持的交互提问类型:
|
|
3
|
+
* - `confirm`:是/否确认,结果为布尔值;
|
|
4
|
+
* - `input`:文本输入,结果为字符串。
|
|
5
|
+
*/
|
|
6
|
+
export type XCliPromptType = 'confirm' | 'input';
|
|
7
|
+
/**
|
|
8
|
+
* 提问类型与返回值类型的映射。
|
|
9
|
+
*/
|
|
10
|
+
export interface XCliPromptResult {
|
|
11
|
+
confirm: boolean;
|
|
12
|
+
input: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 单次交互提问的配置。
|
|
16
|
+
*/
|
|
17
|
+
export interface XCliPromptOptions<T extends XCliPromptType> {
|
|
18
|
+
/** 展示给用户的提示文案。 */
|
|
19
|
+
message: string;
|
|
20
|
+
/** 提问类型,决定返回值类型。 */
|
|
21
|
+
type: T;
|
|
22
|
+
/** 可选的默认值,类型随 `type` 联动。 */
|
|
23
|
+
default?: XCliPromptResult[T];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 命令行交互与表格输出工具。
|
|
27
|
+
*
|
|
28
|
+
* 基于 `inquirer` 与 `cli-table3` 封装:
|
|
29
|
+
* - `prompt`:发起一次确认或文本输入交互,并返回强类型结果;
|
|
30
|
+
* - `table`:将二维数组渲染为对齐的文本表格。
|
|
31
|
+
*/
|
|
32
|
+
export declare class XCli {
|
|
33
|
+
/**
|
|
34
|
+
* 发起一次交互提问并返回结果。
|
|
35
|
+
*
|
|
36
|
+
* @param options 提问配置,`type` 决定返回值类型。
|
|
37
|
+
* @returns 根据 `type` 返回 `boolean`(confirm)或 `string`(input)。
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* await XCli.prompt({ type: 'confirm', message: '是否继续?' }) // true | false
|
|
41
|
+
* await XCli.prompt({ type: 'input', message: '请输入名称' }) // 'demo'
|
|
42
|
+
*/
|
|
43
|
+
static prompt<T extends XCliPromptType>(options: XCliPromptOptions<T>): Promise<XCliPromptResult[T]>;
|
|
44
|
+
/**
|
|
45
|
+
* 将二维数组渲染为对齐的文本表格。
|
|
46
|
+
*
|
|
47
|
+
* 返回纯文本(不含 ANSI 颜色码),保证在任意终端环境下输出一致。
|
|
48
|
+
*
|
|
49
|
+
* @param data 表格行数据,每行为一个单元格数组。
|
|
50
|
+
* @returns 使用 Unicode 边框绘制的表格字符串。
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* XCli.table([
|
|
54
|
+
* ['姓名', '年龄'],
|
|
55
|
+
* ['张三', '18'],
|
|
56
|
+
* ])
|
|
57
|
+
* // ┌──────┬──────┐
|
|
58
|
+
* // │ 姓名 │ 年龄 │
|
|
59
|
+
* // ├──────┼──────┤
|
|
60
|
+
* // │ 张三 │ 18 │
|
|
61
|
+
* // └──────┴──────┘
|
|
62
|
+
*/
|
|
63
|
+
static table(data: any[][]): string;
|
|
64
|
+
}
|
package/lib/cli.mjs
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import Table from "cli-table3";
|
|
2
|
+
import inquirer from "inquirer";
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
/**
|
|
5
|
+
* 命令行交互与表格输出工具。
|
|
6
|
+
*
|
|
7
|
+
* 基于 `inquirer` 与 `cli-table3` 封装:
|
|
8
|
+
* - `prompt`:发起一次确认或文本输入交互,并返回强类型结果;
|
|
9
|
+
* - `table`:将二维数组渲染为对齐的文本表格。
|
|
10
|
+
*/
|
|
11
|
+
var XCli = class {
|
|
12
|
+
/**
|
|
13
|
+
* 发起一次交互提问并返回结果。
|
|
14
|
+
*
|
|
15
|
+
* @param options 提问配置,`type` 决定返回值类型。
|
|
16
|
+
* @returns 根据 `type` 返回 `boolean`(confirm)或 `string`(input)。
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* await XCli.prompt({ type: 'confirm', message: '是否继续?' }) // true | false
|
|
20
|
+
* await XCli.prompt({ type: 'input', message: '请输入名称' }) // 'demo'
|
|
21
|
+
*/
|
|
22
|
+
static async prompt(options) {
|
|
23
|
+
const { x } = await inquirer.prompt({
|
|
24
|
+
name: "x",
|
|
25
|
+
message: options.message,
|
|
26
|
+
type: options.type,
|
|
27
|
+
default: options.default
|
|
28
|
+
});
|
|
29
|
+
return x;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 将二维数组渲染为对齐的文本表格。
|
|
33
|
+
*
|
|
34
|
+
* 返回纯文本(不含 ANSI 颜色码),保证在任意终端环境下输出一致。
|
|
35
|
+
*
|
|
36
|
+
* @param data 表格行数据,每行为一个单元格数组。
|
|
37
|
+
* @returns 使用 Unicode 边框绘制的表格字符串。
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* XCli.table([
|
|
41
|
+
* ['姓名', '年龄'],
|
|
42
|
+
* ['张三', '18'],
|
|
43
|
+
* ])
|
|
44
|
+
* // ┌──────┬──────┐
|
|
45
|
+
* // │ 姓名 │ 年龄 │
|
|
46
|
+
* // ├──────┼──────┤
|
|
47
|
+
* // │ 张三 │ 18 │
|
|
48
|
+
* // └──────┴──────┘
|
|
49
|
+
*/
|
|
50
|
+
static table(data) {
|
|
51
|
+
const table = new Table({ style: {
|
|
52
|
+
head: [],
|
|
53
|
+
border: []
|
|
54
|
+
} });
|
|
55
|
+
table.push(...data);
|
|
56
|
+
return table.toString();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
export { XCli };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 剪贴板文本/HTML 读写工具。
|
|
3
|
+
*
|
|
4
|
+
* 说明:
|
|
5
|
+
* - `readText` / `writeText` 使用 `clipboardy`,跨平台处理纯文本;
|
|
6
|
+
* - `readHtml` / `writeHtml` 在不同平台走不同实现:
|
|
7
|
+
* - macOS:`osascript` + AppleScript HTML 数据;
|
|
8
|
+
* - Windows:`powershell` + `HTML Format`(CF_HTML);
|
|
9
|
+
* - 其他平台:抛出不支持错误。
|
|
10
|
+
*/
|
|
11
|
+
export declare class XClipboard {
|
|
12
|
+
/**
|
|
13
|
+
* 构建 Windows CF_HTML 文本。
|
|
14
|
+
*
|
|
15
|
+
* 参考规范中 Start/End 偏移均按字节计数(UTF-8)。
|
|
16
|
+
*/
|
|
17
|
+
private static toWindowsCfHtml;
|
|
18
|
+
/**
|
|
19
|
+
* 从 Windows `HTML Format` 文本中提取 fragment。
|
|
20
|
+
*
|
|
21
|
+
* 若缺少偏移字段,会尝试用标记提取;再失败时返回原始文本。
|
|
22
|
+
*/
|
|
23
|
+
private static fromWindowsCfHtml;
|
|
24
|
+
/**
|
|
25
|
+
* 将 PowerShell 脚本编码为 `-EncodedCommand` 可执行格式(UTF-16LE)。
|
|
26
|
+
*/
|
|
27
|
+
private static buildPowerShellCommand;
|
|
28
|
+
/**
|
|
29
|
+
* 读取纯文本剪贴板内容。
|
|
30
|
+
*/
|
|
31
|
+
static readText(): Promise<string>;
|
|
32
|
+
/**
|
|
33
|
+
* 读取 HTML 剪贴板内容(macOS / Windows)。
|
|
34
|
+
*
|
|
35
|
+
* - macOS:读取 AppleScript `«data HTML...»` 十六进制文本并解码;
|
|
36
|
+
* - Windows:读取 `HTML Format`(CF_HTML)并提取 fragment。
|
|
37
|
+
*/
|
|
38
|
+
static readHtml(): Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* 写入纯文本到剪贴板。
|
|
41
|
+
*/
|
|
42
|
+
static writeText(text: string): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* 写入 HTML 到剪贴板(macOS / Windows)。
|
|
45
|
+
*
|
|
46
|
+
* - macOS:将 HTML 编码为十六进制后写入 AppleScript HTML 数据;
|
|
47
|
+
* - Windows:封装为 CF_HTML(`HTML Format`)后调用 PowerShell 写入。
|
|
48
|
+
*/
|
|
49
|
+
static writeHtml(html: string): Promise<void>;
|
|
50
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { XCmd } from "./cmd.mjs";
|
|
2
|
+
import clipboardy from "clipboardy";
|
|
3
|
+
// src/clipboard.ts
|
|
4
|
+
/**
|
|
5
|
+
* 剪贴板文本/HTML 读写工具。
|
|
6
|
+
*
|
|
7
|
+
* 说明:
|
|
8
|
+
* - `readText` / `writeText` 使用 `clipboardy`,跨平台处理纯文本;
|
|
9
|
+
* - `readHtml` / `writeHtml` 在不同平台走不同实现:
|
|
10
|
+
* - macOS:`osascript` + AppleScript HTML 数据;
|
|
11
|
+
* - Windows:`powershell` + `HTML Format`(CF_HTML);
|
|
12
|
+
* - 其他平台:抛出不支持错误。
|
|
13
|
+
*/
|
|
14
|
+
var XClipboard = class XClipboard {
|
|
15
|
+
/**
|
|
16
|
+
* 构建 Windows CF_HTML 文本。
|
|
17
|
+
*
|
|
18
|
+
* 参考规范中 Start/End 偏移均按字节计数(UTF-8)。
|
|
19
|
+
*/
|
|
20
|
+
static toWindowsCfHtml(fragmentHtml) {
|
|
21
|
+
const htmlPrefix = "<!DOCTYPE html><html><body><!--StartFragment-->";
|
|
22
|
+
const html = `${htmlPrefix}${fragmentHtml}<!--EndFragment--></body></html>`;
|
|
23
|
+
const startHtml = Buffer.byteLength("Version:0.9\r\nStartHTML:0000000000\r\nEndHTML:0000000000\r\nStartFragment:0000000000\r\nEndFragment:0000000000\r\n", "utf8");
|
|
24
|
+
const startFragment = startHtml + Buffer.byteLength(htmlPrefix, "utf8");
|
|
25
|
+
const endFragment = startFragment + Buffer.byteLength(fragmentHtml, "utf8");
|
|
26
|
+
const endHtml = startHtml + Buffer.byteLength(html, "utf8");
|
|
27
|
+
const pad = (num) => num.toString().padStart(10, "0");
|
|
28
|
+
return `${`Version:0.9\r
|
|
29
|
+
StartHTML:${pad(startHtml)}\r\nEndHTML:${pad(endHtml)}\r\nStartFragment:${pad(startFragment)}\r\nEndFragment:${pad(endFragment)}\r\n`}${html}`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 从 Windows `HTML Format` 文本中提取 fragment。
|
|
33
|
+
*
|
|
34
|
+
* 若缺少偏移字段,会尝试用标记提取;再失败时返回原始文本。
|
|
35
|
+
*/
|
|
36
|
+
static fromWindowsCfHtml(value) {
|
|
37
|
+
const startMatch = value.match(/StartFragment:(\d+)/);
|
|
38
|
+
const endMatch = value.match(/EndFragment:(\d+)/);
|
|
39
|
+
if (startMatch && endMatch) {
|
|
40
|
+
const start = Number(startMatch[1]);
|
|
41
|
+
const end = Number(endMatch[1]);
|
|
42
|
+
if (Number.isFinite(start) && Number.isFinite(end) && end >= start) {
|
|
43
|
+
const bytes = Buffer.from(value, "utf8");
|
|
44
|
+
if (start >= 0 && end <= bytes.length) return bytes.subarray(start, end).toString("utf8");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const markerMatch = value.match(/<!--StartFragment-->([\s\S]*?)<!--EndFragment-->/);
|
|
48
|
+
if (markerMatch) return markerMatch[1];
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 将 PowerShell 脚本编码为 `-EncodedCommand` 可执行格式(UTF-16LE)。
|
|
53
|
+
*/
|
|
54
|
+
static buildPowerShellCommand(script) {
|
|
55
|
+
return `powershell -NoProfile -NonInteractive -STA -EncodedCommand ${Buffer.from(script, "utf16le").toString("base64")}`;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 读取纯文本剪贴板内容。
|
|
59
|
+
*/
|
|
60
|
+
static async readText() {
|
|
61
|
+
return clipboardy.read();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 读取 HTML 剪贴板内容(macOS / Windows)。
|
|
65
|
+
*
|
|
66
|
+
* - macOS:读取 AppleScript `«data HTML...»` 十六进制文本并解码;
|
|
67
|
+
* - Windows:读取 `HTML Format`(CF_HTML)并提取 fragment。
|
|
68
|
+
*/
|
|
69
|
+
static async readHtml() {
|
|
70
|
+
if (process.platform === "darwin") {
|
|
71
|
+
const { result: hex } = await XCmd.exec(`osascript -e "the clipboard as «class HTML»"`);
|
|
72
|
+
const normalized = hex.trim();
|
|
73
|
+
const matched = normalized.match(/^«data HTML([0-9a-fA-F]*)»$/);
|
|
74
|
+
if (!matched) throw new Error(`读取剪贴板 HTML 失败,返回内容格式无效: ${normalized}`);
|
|
75
|
+
return Buffer.from(matched[1], "hex").toString();
|
|
76
|
+
}
|
|
77
|
+
if (process.platform === "win32") {
|
|
78
|
+
const command = XClipboard.buildPowerShellCommand([
|
|
79
|
+
"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8",
|
|
80
|
+
"Add-Type -AssemblyName System.Windows.Forms",
|
|
81
|
+
"$data = [System.Windows.Forms.Clipboard]::GetData('HTML Format')",
|
|
82
|
+
"if ($null -eq $data) { return }",
|
|
83
|
+
"Write-Output $data"
|
|
84
|
+
].join("; "));
|
|
85
|
+
const { result } = await XCmd.exec(command);
|
|
86
|
+
return XClipboard.fromWindowsCfHtml(result.trim());
|
|
87
|
+
}
|
|
88
|
+
throw new Error(`当前平台不支持读取 HTML 剪贴板: ${process.platform}`);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 写入纯文本到剪贴板。
|
|
92
|
+
*/
|
|
93
|
+
static async writeText(text) {
|
|
94
|
+
await clipboardy.write(text);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* 写入 HTML 到剪贴板(macOS / Windows)。
|
|
98
|
+
*
|
|
99
|
+
* - macOS:将 HTML 编码为十六进制后写入 AppleScript HTML 数据;
|
|
100
|
+
* - Windows:封装为 CF_HTML(`HTML Format`)后调用 PowerShell 写入。
|
|
101
|
+
*/
|
|
102
|
+
static async writeHtml(html) {
|
|
103
|
+
if (process.platform === "darwin") {
|
|
104
|
+
const hex = Buffer.from(html).toString("hex");
|
|
105
|
+
await XCmd.exec(`osascript -e "set the clipboard to «data HTML${hex}»"`);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (process.platform === "win32") {
|
|
109
|
+
const cfHtml = XClipboard.toWindowsCfHtml(html);
|
|
110
|
+
const cfHtmlBase64 = Buffer.from(cfHtml, "utf8").toString("base64");
|
|
111
|
+
const command = XClipboard.buildPowerShellCommand([
|
|
112
|
+
"$cfHtml = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('" + cfHtmlBase64 + "'))",
|
|
113
|
+
"Add-Type -AssemblyName System.Windows.Forms",
|
|
114
|
+
"[System.Windows.Forms.Clipboard]::SetData('HTML Format', $cfHtml)"
|
|
115
|
+
].join("; "));
|
|
116
|
+
await XCmd.exec(command);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
throw new Error(`当前平台不支持写入 HTML 剪贴板: ${process.platform}`);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
export { XClipboard };
|