@maiyunnet/kebab 2.0.7 → 2.0.9
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/index.d.ts +11 -1
- package/index.js +13 -1
- package/lib/buffer.d.ts +25 -0
- package/lib/buffer.js +30 -5
- package/lib/captcha.d.ts +15 -0
- package/lib/captcha.js +20 -0
- package/lib/consistent.d.ts +51 -0
- package/lib/consistent.js +59 -0
- package/lib/core.d.ts +134 -0
- package/lib/core.js +176 -0
- package/lib/crypto.d.ts +75 -6
- package/lib/crypto.js +206 -38
- package/lib/db.d.ts +104 -0
- package/lib/db.js +126 -0
- package/lib/dns.d.ts +51 -0
- package/lib/dns.js +54 -2
- package/lib/fs.d.ts +100 -0
- package/lib/fs.js +118 -0
- package/lib/jwt.d.ts +43 -0
- package/lib/jwt.js +45 -0
- package/lib/kv.d.ts +362 -0
- package/lib/kv.js +377 -0
- package/lib/lan.d.ts +6 -0
- package/lib/lan.js +7 -0
- package/lib/net/formdata.d.ts +38 -0
- package/lib/net/formdata.js +43 -0
- package/lib/net/request.d.ts +62 -0
- package/lib/net/request.js +57 -0
- package/lib/net/response.d.ts +21 -0
- package/lib/net/response.js +16 -0
- package/lib/net.d.ts +86 -0
- package/lib/net.js +140 -0
- package/lib/s3.d.ts +52 -0
- package/lib/s3.js +51 -0
- package/lib/scan.d.ts +52 -0
- package/lib/scan.js +84 -0
- package/lib/session.d.ts +31 -0
- package/lib/session.js +52 -1
- package/lib/sql.d.ts +176 -0
- package/lib/sql.js +287 -2
- package/lib/ssh/sftp.d.ts +106 -0
- package/lib/ssh/sftp.js +106 -0
- package/lib/ssh/shell.d.ts +37 -0
- package/lib/ssh/shell.js +31 -0
- package/lib/ssh.d.ts +32 -0
- package/lib/ssh.js +32 -0
- package/lib/text.d.ts +131 -0
- package/lib/text.js +188 -0
- package/lib/time.d.ts +53 -0
- package/lib/time.js +55 -0
- package/lib/ws.d.ts +68 -0
- package/lib/ws.js +74 -0
- package/lib/zip.d.ts +53 -0
- package/lib/zip.js +73 -0
- package/lib/zlib.d.ts +76 -0
- package/lib/zlib.js +78 -0
- package/main.d.ts +5 -0
- package/main.js +12 -0
- package/package.json +3 -2
- package/sys/child.js +104 -0
- package/sys/cmd.js +28 -0
- package/sys/ctr.d.ts +166 -0
- package/sys/ctr.js +177 -0
- package/sys/master.js +63 -0
- package/sys/mod.d.ts +266 -0
- package/sys/mod.js +335 -0
- package/sys/route.d.ts +34 -0
- package/sys/route.js +164 -0
- package/www/example/ctr/test.d.ts +3 -0
- package/www/example/ctr/test.js +63 -1
- package/www/example/mod/test.js +14 -0
- package/www/example/mod/testdata.js +9 -0
- package/www/example/ws/test.js +1 -0
- package/.VSCodeCounter/2025-02-14_14-46-44/details.md +0 -82
- package/.VSCodeCounter/2025-02-14_14-46-44/diff-details.md +0 -15
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.csv +0 -2
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.md +0 -19
- package/.VSCodeCounter/2025-02-14_14-46-44/diff.txt +0 -22
- package/.VSCodeCounter/2025-02-14_14-46-44/results.csv +0 -69
- package/.VSCodeCounter/2025-02-14_14-46-44/results.json +0 -1
- package/.VSCodeCounter/2025-02-14_14-46-44/results.md +0 -48
- package/.VSCodeCounter/2025-02-14_14-46-44/results.txt +0 -118
- package/.vscode/tasks.json +0 -15
package/lib/text.d.ts
CHANGED
|
@@ -1,40 +1,171 @@
|
|
|
1
1
|
import * as types from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* --- 将文件大小格式化为带单位的字符串 ---
|
|
4
|
+
* @param size 文件大小
|
|
5
|
+
* @param spliter 分隔符
|
|
6
|
+
*/
|
|
2
7
|
export declare function sizeFormat(size: number, spliter?: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* --- 格式化一段 URL ---
|
|
10
|
+
* @param url
|
|
11
|
+
*/
|
|
3
12
|
export declare function parseUrl(url: string): types.IUrlParse;
|
|
13
|
+
/**
|
|
14
|
+
* --- 将相对路径根据基准路径进行转换 ---
|
|
15
|
+
* @param from 基准路径
|
|
16
|
+
* @param to 相对路径
|
|
17
|
+
*/
|
|
4
18
|
export declare function urlResolve(from: string, to: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* --- 将路径中的 ../ ./ 都按规范妥善处理 ---
|
|
21
|
+
* @param url 要处理的地址
|
|
22
|
+
*/
|
|
5
23
|
export declare function urlAtom(url: string): string;
|
|
6
24
|
export declare const REGEXP_EMAIL: RegExp;
|
|
25
|
+
/**
|
|
26
|
+
* --- 是否是邮件地址 ---
|
|
27
|
+
* @param email
|
|
28
|
+
*/
|
|
7
29
|
export declare function isEMail(email: string): boolean;
|
|
8
30
|
export declare const REGEXP_IPV4: RegExp;
|
|
31
|
+
/**
|
|
32
|
+
* --- 是否是 IPv4 ---
|
|
33
|
+
* @param ip
|
|
34
|
+
*/
|
|
9
35
|
export declare function isIPv4(ip: string): boolean;
|
|
10
36
|
export declare const REGEXP_IPV6: RegExp;
|
|
37
|
+
/**
|
|
38
|
+
* --- 是否是 IPv6 ---
|
|
39
|
+
* @param ip
|
|
40
|
+
*/
|
|
11
41
|
export declare function isIPv6(ip: string): boolean;
|
|
12
42
|
export declare const REGEXP_DOMAIN: RegExp;
|
|
43
|
+
/**
|
|
44
|
+
* --- 判断是否是域名 ---
|
|
45
|
+
* @param string $domain
|
|
46
|
+
* @return bool
|
|
47
|
+
*/
|
|
13
48
|
export declare function isDomain(domain: string): boolean;
|
|
14
49
|
export declare const REGEXP_ASCII: RegExp;
|
|
50
|
+
/**
|
|
51
|
+
* --- 判断是否在 ascii 字符集内,仅可输入部分 ---
|
|
52
|
+
* @param text 要判断的文本
|
|
53
|
+
*/
|
|
15
54
|
export declare function isAscii(text: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* --- 换行替换为别的 ---
|
|
57
|
+
* @param str 要替换的字符串
|
|
58
|
+
* @param to 换行替换符
|
|
59
|
+
*/
|
|
16
60
|
export declare function nlReplace(str: string, to?: string): string;
|
|
61
|
+
/** 解析后的 domain */
|
|
17
62
|
export interface IDomain {
|
|
18
63
|
tld: string | null;
|
|
19
64
|
sld: string | null;
|
|
20
65
|
domain: string | null;
|
|
21
66
|
sub: string | null;
|
|
22
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* --- 解析域名并获取 tld/sld/domain/sub ---
|
|
70
|
+
* @param domain 域名
|
|
71
|
+
*/
|
|
23
72
|
export declare function parseDomain(domain: string): Promise<IDomain>;
|
|
73
|
+
/**
|
|
74
|
+
* --- 传入正则进行匹配 str 是否有一项满足 ---
|
|
75
|
+
* @param str 要检测的字符串
|
|
76
|
+
* @param regs 正则列表
|
|
77
|
+
*/
|
|
24
78
|
export declare function match(str: string, regs: RegExp[]): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* --- 判断手机号是否是 11 位,不做真实性校验 ---
|
|
81
|
+
* @param p 手机号
|
|
82
|
+
*/
|
|
25
83
|
export declare function isPhoneCN(p: string): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* --- 是否是中国大陆身份证号码 ---
|
|
86
|
+
* @param idcard 身份证号
|
|
87
|
+
*/
|
|
26
88
|
export declare function isIdCardCN(idcard: string): boolean;
|
|
89
|
+
/**
|
|
90
|
+
* --- 将对象转换为 query string ---
|
|
91
|
+
* @param query 要转换的对象
|
|
92
|
+
* @param encode 是否转义
|
|
93
|
+
*/
|
|
27
94
|
export declare function queryStringify(query: Record<string, any>, encode?: boolean): string;
|
|
95
|
+
/**
|
|
96
|
+
* --- 将 query string 转换为对象 ---
|
|
97
|
+
* @param query 要转换的字符串
|
|
98
|
+
*/
|
|
28
99
|
export declare function queryParse(query: string): Record<string, string | string[]>;
|
|
100
|
+
/**
|
|
101
|
+
* --- HTML 特殊字符转换为实体字符 ---
|
|
102
|
+
* @param html 待转换的 HTML
|
|
103
|
+
*/
|
|
29
104
|
export declare function htmlescape(html: string): string;
|
|
105
|
+
/**
|
|
106
|
+
* --- 判断是否是绝对路径,是返回 true,相对路径返回 false ---
|
|
107
|
+
* @param path 要判断的路径字符串
|
|
108
|
+
*/
|
|
30
109
|
export declare function isRealPath(path: string): boolean;
|
|
110
|
+
/**
|
|
111
|
+
* --- 获取文件名 ---
|
|
112
|
+
* @param path 文件路径
|
|
113
|
+
*/
|
|
31
114
|
export declare function getFilename(path: string): string;
|
|
115
|
+
/**
|
|
116
|
+
* --- 将普通的返回 JSON 对象序列化为字符串,Mutton 不能使用 ---
|
|
117
|
+
* @param o 返回 JSON 对象
|
|
118
|
+
*/
|
|
32
119
|
export declare function stringifyResult(rtn: types.Json): string;
|
|
120
|
+
/**
|
|
121
|
+
* --- 将字符串解析为对象,返回 false 代表解析失败,支持 BigInt,Kebab true, Mutton false ---
|
|
122
|
+
* @param str 要解析的 json 字符串
|
|
123
|
+
*/
|
|
33
124
|
export declare function parseJson(str: string): any;
|
|
125
|
+
/**
|
|
126
|
+
* --- 将对象转换为 json 字符串,返回 false 代表解析失败,支持 BigInt,Kebab true, Mutton false ---
|
|
127
|
+
* @param obj 要转换的 json 对象
|
|
128
|
+
* @param space 美化方式
|
|
129
|
+
*/
|
|
34
130
|
export declare function stringifyJson(obj: types.Json, space?: string | number): string;
|
|
131
|
+
/**
|
|
132
|
+
* --- 输出文本格式的 buffer ---
|
|
133
|
+
* @param buf 原始 buffer
|
|
134
|
+
*/
|
|
135
|
+
export declare function stringifyBuffer(buf: Buffer): string;
|
|
35
136
|
type TFalsy = false | '' | 0 | null | undefined | typeof NaN;
|
|
137
|
+
/**
|
|
138
|
+
* --- 判断一个值是否是虚假的(为 null/undefined/空字符串/false/0) ---
|
|
139
|
+
* @param val 要判断的值
|
|
140
|
+
*/
|
|
36
141
|
export declare function isFalsy(val: any): val is TFalsy;
|
|
142
|
+
/**
|
|
143
|
+
* --- 类似 || 运算符的效果 ---
|
|
144
|
+
* @param v1 比对值
|
|
145
|
+
* @param v2 比对值
|
|
146
|
+
*/
|
|
37
147
|
export declare function logicalOr<T, T2>(v1: T, v2: T2): [T] extends [TFalsy] ? T2 : T;
|
|
148
|
+
/**
|
|
149
|
+
* --- 为解决精度问题,将字符串数字转换为整数显示 ---
|
|
150
|
+
* --- 以下几个示例都是当 digits 为 2 时 ---
|
|
151
|
+
* --- str 传入 '1.234',返回 123 ---
|
|
152
|
+
* --- str 传入 '1.235',返回 124 ---
|
|
153
|
+
* --- str 传入 '1.1',返回 110 ---
|
|
154
|
+
* --- str 传入 '6',返回 600 ---
|
|
155
|
+
* @param str 要转换的数字字符串
|
|
156
|
+
* @param digits 小数点右移位数
|
|
157
|
+
*/
|
|
38
158
|
export declare function str2int(str: string, digits?: number): number;
|
|
159
|
+
/**
|
|
160
|
+
* --- 为解决精度问题,将整数转换为小数字符串 ---
|
|
161
|
+
* --- 以下几个示例都是当 digits 为 3、decimal 为 2 时 ---
|
|
162
|
+
* --- int 传入 2341,返回 '2.34' ---
|
|
163
|
+
* --- int 传入 2345,返回 '2.35' ---
|
|
164
|
+
* --- int 传入 23,返回 '0.02' ---
|
|
165
|
+
* --- int 传入 2,返回 '0.00' ---
|
|
166
|
+
* @param int 要转换的整数
|
|
167
|
+
* @param digits 小数点左移位数
|
|
168
|
+
* @param decimal 最终保留的小数位数
|
|
169
|
+
*/
|
|
39
170
|
export declare function int2str(int: number, digits?: number, decimal?: number): string;
|
|
40
171
|
export {};
|
package/lib/text.js
CHANGED
|
@@ -56,12 +56,23 @@ exports.getFilename = getFilename;
|
|
|
56
56
|
exports.stringifyResult = stringifyResult;
|
|
57
57
|
exports.parseJson = parseJson;
|
|
58
58
|
exports.stringifyJson = stringifyJson;
|
|
59
|
+
exports.stringifyBuffer = stringifyBuffer;
|
|
59
60
|
exports.isFalsy = isFalsy;
|
|
60
61
|
exports.logicalOr = logicalOr;
|
|
61
62
|
exports.str2int = str2int;
|
|
62
63
|
exports.int2str = int2str;
|
|
64
|
+
/**
|
|
65
|
+
* Project: Kebab, User: JianSuoQiYue
|
|
66
|
+
* Date: 2019-5-15 16:49:39
|
|
67
|
+
* Last: 2020-04-06 20:51:06, 2022-9-29 15:18:16, 2022-12-29 00:01:30, 2024-3-6 17:53:14, 2024-5-31 17:29:52, 2025-6-13 15:47:02
|
|
68
|
+
*/
|
|
63
69
|
const kebab = __importStar(require("../index"));
|
|
64
70
|
const fs = __importStar(require("./fs"));
|
|
71
|
+
/**
|
|
72
|
+
* --- 将文件大小格式化为带单位的字符串 ---
|
|
73
|
+
* @param size 文件大小
|
|
74
|
+
* @param spliter 分隔符
|
|
75
|
+
*/
|
|
65
76
|
function sizeFormat(size, spliter = ' ') {
|
|
66
77
|
const units = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
|
67
78
|
let i = 0;
|
|
@@ -70,7 +81,12 @@ function sizeFormat(size, spliter = ' ') {
|
|
|
70
81
|
}
|
|
71
82
|
return (Math.round(size * 100) / 100).toString() + spliter + units[i];
|
|
72
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* --- 格式化一段 URL ---
|
|
86
|
+
* @param url
|
|
87
|
+
*/
|
|
73
88
|
function parseUrl(url) {
|
|
89
|
+
// --- test: https://ab-3dc:aak9()$@github.com:80/nodejs/node/blob/master/lib/url.js?mail=abc@def.com#223 ---
|
|
74
90
|
const rtn = {
|
|
75
91
|
'protocol': null,
|
|
76
92
|
'auth': null,
|
|
@@ -114,6 +130,7 @@ function parseUrl(url) {
|
|
|
114
130
|
const authStr = url.slice(0, auth);
|
|
115
131
|
const authSplit = authStr.indexOf(':');
|
|
116
132
|
if (authSplit > -1) {
|
|
133
|
+
// --- 有密码 ---
|
|
117
134
|
rtn['user'] = authStr.slice(0, authSplit);
|
|
118
135
|
rtn['pass'] = authStr.slice(authSplit + 1);
|
|
119
136
|
rtn['auth'] = rtn['user'] + ':' + rtn['pass'];
|
|
@@ -138,28 +155,43 @@ function parseUrl(url) {
|
|
|
138
155
|
}
|
|
139
156
|
}
|
|
140
157
|
else {
|
|
158
|
+
// --- 没有 protocol ---
|
|
141
159
|
rtn['pathname'] = url;
|
|
142
160
|
}
|
|
161
|
+
// --- 组合 ---
|
|
143
162
|
rtn['path'] = rtn['pathname'] + (rtn['query'] ? '?' + rtn['query'] : '');
|
|
144
163
|
return rtn;
|
|
145
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* --- 将相对路径根据基准路径进行转换 ---
|
|
167
|
+
* @param from 基准路径
|
|
168
|
+
* @param to 相对路径
|
|
169
|
+
*/
|
|
146
170
|
function urlResolve(from, to) {
|
|
147
171
|
from = from.replace('\\', '/');
|
|
148
172
|
to = to.replace('\\', '/');
|
|
173
|
+
// --- to 为空,直接返回 form ---
|
|
149
174
|
if (to === '') {
|
|
150
175
|
return urlAtom(from);
|
|
151
176
|
}
|
|
177
|
+
// --- 获取 from 的 scheme, host, path ---
|
|
152
178
|
const f = parseUrl(from);
|
|
179
|
+
// --- 以 // 开头的,加上 from 的 protocol 返回 ---
|
|
153
180
|
if (to.startsWith('//')) {
|
|
154
181
|
return urlAtom(f.protocol ? f.protocol + to : to);
|
|
155
182
|
}
|
|
156
183
|
if (f.protocol) {
|
|
184
|
+
// --- 获取小写的 protocol ---
|
|
157
185
|
from = f.protocol + from.slice(f.protocol.length);
|
|
158
186
|
}
|
|
187
|
+
// --- 获取 to 的 scheme, host, path ---
|
|
159
188
|
const t = parseUrl(to);
|
|
189
|
+
// --- 已经是绝对路径,直接返回 ---
|
|
160
190
|
if (t.protocol) {
|
|
191
|
+
// --- 获取小写的 protocol ---
|
|
161
192
|
return urlAtom(t.protocol + to.slice(t.protocol.length));
|
|
162
193
|
}
|
|
194
|
+
// --- # 或 ? 替换后返回 ---
|
|
163
195
|
if (to.startsWith('#') || to.startsWith('?')) {
|
|
164
196
|
const sp = from.indexOf(to[0]);
|
|
165
197
|
if (sp !== -1) {
|
|
@@ -169,25 +201,39 @@ function urlResolve(from, to) {
|
|
|
169
201
|
return urlAtom(from + to);
|
|
170
202
|
}
|
|
171
203
|
}
|
|
204
|
+
// --- 处理后面的尾随路径 ---
|
|
172
205
|
let abs = (f.auth ? f.auth + '@' : '') + (f.host ?? '');
|
|
173
206
|
if (to.startsWith('/')) {
|
|
207
|
+
// -- abs 类似是 /xx/xx ---
|
|
174
208
|
abs += to;
|
|
175
209
|
}
|
|
176
210
|
else {
|
|
211
|
+
// --- to 是 xx/xx 这样的 ---
|
|
212
|
+
// --- 移除基准 path 不是路径的部分,如 /ab/c 变成了 /ab,/ab 变成了 空 ---
|
|
177
213
|
const path = f.pathname.replace(/\/[^/]*$/g, '');
|
|
214
|
+
// --- abs 是 /xx/xx 了,因为如果 path 是空,则跟上了 /,如果 path 不为空,也是 / 开头 ---
|
|
178
215
|
abs += path + '/' + to;
|
|
179
216
|
}
|
|
217
|
+
// --- 返回最终结果 ---
|
|
180
218
|
if (f.protocol && (f.protocol !== 'file:') && !f.host) {
|
|
219
|
+
// --- 类似 c:/ ---
|
|
181
220
|
return urlAtom(f.protocol + abs);
|
|
182
221
|
}
|
|
183
222
|
else {
|
|
223
|
+
// --- 类似 http:// ---
|
|
184
224
|
return urlAtom((f.protocol ? f.protocol + '//' : '') + abs);
|
|
185
225
|
}
|
|
186
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* --- 将路径中的 ../ ./ 都按规范妥善处理 ---
|
|
229
|
+
* @param url 要处理的地址
|
|
230
|
+
*/
|
|
187
231
|
function urlAtom(url) {
|
|
232
|
+
// --- 删掉 ./ ---
|
|
188
233
|
while (url.includes('/./')) {
|
|
189
234
|
url = url.replace(/\/\.\//g, '/');
|
|
190
235
|
}
|
|
236
|
+
// --- 删掉 ../ ---
|
|
191
237
|
while (/\/(?!\.\.)[^/]+\/\.\.\//.test(url)) {
|
|
192
238
|
url = url.replace(/\/(?!\.\.)[^/]+\/\.\.\//g, '/');
|
|
193
239
|
}
|
|
@@ -195,25 +241,51 @@ function urlAtom(url) {
|
|
|
195
241
|
return url;
|
|
196
242
|
}
|
|
197
243
|
exports.REGEXP_EMAIL = /^[-_\w.]+@[-_\w.]+\.([a-zA-Z]+)$/i;
|
|
244
|
+
/**
|
|
245
|
+
* --- 是否是邮件地址 ---
|
|
246
|
+
* @param email
|
|
247
|
+
*/
|
|
198
248
|
function isEMail(email) {
|
|
199
249
|
return exports.REGEXP_EMAIL.test(email);
|
|
200
250
|
}
|
|
201
251
|
exports.REGEXP_IPV4 = /^[0-9]{1,3}(\.[0-9]{1,3}){3}$/i;
|
|
252
|
+
/**
|
|
253
|
+
* --- 是否是 IPv4 ---
|
|
254
|
+
* @param ip
|
|
255
|
+
*/
|
|
202
256
|
function isIPv4(ip) {
|
|
203
257
|
return exports.REGEXP_IPV4.test(ip);
|
|
204
258
|
}
|
|
205
259
|
exports.REGEXP_IPV6 = /^(\w*?:){2,7}[\w.]*$/i;
|
|
260
|
+
/**
|
|
261
|
+
* --- 是否是 IPv6 ---
|
|
262
|
+
* @param ip
|
|
263
|
+
*/
|
|
206
264
|
function isIPv6(ip) {
|
|
207
265
|
return exports.REGEXP_IPV6.test(ip + ':');
|
|
208
266
|
}
|
|
209
267
|
exports.REGEXP_DOMAIN = /^.+?\.((?![0-9]).)+$/i;
|
|
268
|
+
/**
|
|
269
|
+
* --- 判断是否是域名 ---
|
|
270
|
+
* @param string $domain
|
|
271
|
+
* @return bool
|
|
272
|
+
*/
|
|
210
273
|
function isDomain(domain) {
|
|
211
274
|
return exports.REGEXP_DOMAIN.test(domain);
|
|
212
275
|
}
|
|
213
276
|
exports.REGEXP_ASCII = /^[\x20-\x7E]*$/;
|
|
277
|
+
/**
|
|
278
|
+
* --- 判断是否在 ascii 字符集内,仅可输入部分 ---
|
|
279
|
+
* @param text 要判断的文本
|
|
280
|
+
*/
|
|
214
281
|
function isAscii(text) {
|
|
215
282
|
return exports.REGEXP_ASCII.test(text);
|
|
216
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* --- 换行替换为别的 ---
|
|
286
|
+
* @param str 要替换的字符串
|
|
287
|
+
* @param to 换行替换符
|
|
288
|
+
*/
|
|
217
289
|
function nlReplace(str, to = '\n') {
|
|
218
290
|
str = str.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
219
291
|
if (to !== '\n') {
|
|
@@ -221,7 +293,12 @@ function nlReplace(str, to = '\n') {
|
|
|
221
293
|
}
|
|
222
294
|
return str;
|
|
223
295
|
}
|
|
296
|
+
/** Tld 列表 */
|
|
224
297
|
let tldList;
|
|
298
|
+
/**
|
|
299
|
+
* --- 解析域名并获取 tld/sld/domain/sub ---
|
|
300
|
+
* @param domain 域名
|
|
301
|
+
*/
|
|
225
302
|
async function parseDomain(domain) {
|
|
226
303
|
const rtn = {
|
|
227
304
|
tld: null,
|
|
@@ -243,13 +320,16 @@ async function parseDomain(domain) {
|
|
|
243
320
|
}
|
|
244
321
|
const last2 = (arr[arr.length - 2] + '.' + arr[arr.length - 1]).toLowerCase();
|
|
245
322
|
if (tldList.includes(last2)) {
|
|
323
|
+
// --- last2 就是 tld ---
|
|
246
324
|
rtn.tld = last2;
|
|
247
325
|
if (arr.length === 2) {
|
|
326
|
+
// --- 没有 sld ---
|
|
248
327
|
rtn.domain = last2;
|
|
249
328
|
return rtn;
|
|
250
329
|
}
|
|
251
330
|
rtn.sld = arr[arr.length - 3].toLowerCase();
|
|
252
331
|
rtn.domain = rtn.sld + '.' + rtn.tld;
|
|
332
|
+
// --- 判断是否有 sub ---
|
|
253
333
|
if (arr.length === 3) {
|
|
254
334
|
return rtn;
|
|
255
335
|
}
|
|
@@ -260,6 +340,7 @@ async function parseDomain(domain) {
|
|
|
260
340
|
rtn.tld = arr[arr.length - 1].toLowerCase();
|
|
261
341
|
rtn.sld = arr[arr.length - 2].toLowerCase();
|
|
262
342
|
rtn.domain = rtn.sld + '.' + rtn.tld;
|
|
343
|
+
// --- 判断是否有 sub ---
|
|
263
344
|
if (arr.length === 2) {
|
|
264
345
|
return rtn;
|
|
265
346
|
}
|
|
@@ -269,6 +350,11 @@ async function parseDomain(domain) {
|
|
|
269
350
|
}
|
|
270
351
|
return rtn;
|
|
271
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* --- 传入正则进行匹配 str 是否有一项满足 ---
|
|
355
|
+
* @param str 要检测的字符串
|
|
356
|
+
* @param regs 正则列表
|
|
357
|
+
*/
|
|
272
358
|
function match(str, regs) {
|
|
273
359
|
for (const reg of regs) {
|
|
274
360
|
if (reg.test(str)) {
|
|
@@ -277,22 +363,38 @@ function match(str, regs) {
|
|
|
277
363
|
}
|
|
278
364
|
return false;
|
|
279
365
|
}
|
|
366
|
+
// --- 以下是适用于中国大陆的方法 ---
|
|
367
|
+
/**
|
|
368
|
+
* --- 判断手机号是否是 11 位,不做真实性校验 ---
|
|
369
|
+
* @param p 手机号
|
|
370
|
+
*/
|
|
280
371
|
function isPhoneCN(p) {
|
|
281
372
|
return /^1[0-9]{10}$/.test(p);
|
|
282
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* --- 是否是中国大陆身份证号码 ---
|
|
376
|
+
* @param idcard 身份证号
|
|
377
|
+
*/
|
|
283
378
|
function isIdCardCN(idcard) {
|
|
284
379
|
if (idcard.length !== 18) {
|
|
285
380
|
return false;
|
|
286
381
|
}
|
|
382
|
+
// --- 取出本码 ---
|
|
287
383
|
const idcardBase = idcard.slice(0, 17);
|
|
384
|
+
// --- 取出校验码 ---
|
|
288
385
|
const verifyCode = idcard.slice(17, 18);
|
|
386
|
+
// --- 加权因子 ---
|
|
289
387
|
const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
|
|
388
|
+
// --- 校验码对应值 ---
|
|
290
389
|
const verifyCodeList = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
|
|
390
|
+
// --- 根据前17位计算校验码 ---
|
|
291
391
|
let total = BigInt(0);
|
|
292
392
|
for (let i = 0; i < 17; i++) {
|
|
293
393
|
total += BigInt(idcardBase.slice(i, i + 1)) * BigInt(factor[i]);
|
|
294
394
|
}
|
|
395
|
+
// --- 取模 ---
|
|
295
396
|
const mod = total % BigInt(11);
|
|
397
|
+
// --- 比较校验码 ---
|
|
296
398
|
if (verifyCode === verifyCodeList[Number(mod)]) {
|
|
297
399
|
return true;
|
|
298
400
|
}
|
|
@@ -300,6 +402,12 @@ function isIdCardCN(idcard) {
|
|
|
300
402
|
return false;
|
|
301
403
|
}
|
|
302
404
|
}
|
|
405
|
+
// --- 以下 Mutton: false, Kebab: true ---
|
|
406
|
+
/**
|
|
407
|
+
* --- 将对象转换为 query string ---
|
|
408
|
+
* @param query 要转换的对象
|
|
409
|
+
* @param encode 是否转义
|
|
410
|
+
*/
|
|
303
411
|
function queryStringify(query, encode = true) {
|
|
304
412
|
if (encode) {
|
|
305
413
|
return Object.entries(query).map(([k, v]) => {
|
|
@@ -316,6 +424,10 @@ function queryStringify(query, encode = true) {
|
|
|
316
424
|
return `${k}=${v}`;
|
|
317
425
|
}).join('&');
|
|
318
426
|
}
|
|
427
|
+
/**
|
|
428
|
+
* --- 将 query string 转换为对象 ---
|
|
429
|
+
* @param query 要转换的字符串
|
|
430
|
+
*/
|
|
319
431
|
function queryParse(query) {
|
|
320
432
|
const ret = {};
|
|
321
433
|
const arrayKeys = {};
|
|
@@ -346,6 +458,10 @@ function queryParse(query) {
|
|
|
346
458
|
}
|
|
347
459
|
return ret;
|
|
348
460
|
}
|
|
461
|
+
/**
|
|
462
|
+
* --- HTML 特殊字符转换为实体字符 ---
|
|
463
|
+
* @param html 待转换的 HTML
|
|
464
|
+
*/
|
|
349
465
|
function htmlescape(html) {
|
|
350
466
|
const type = typeof html;
|
|
351
467
|
if (type !== 'string') {
|
|
@@ -353,6 +469,10 @@ function htmlescape(html) {
|
|
|
353
469
|
}
|
|
354
470
|
return html.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/'/g, '"');
|
|
355
471
|
}
|
|
472
|
+
/**
|
|
473
|
+
* --- 判断是否是绝对路径,是返回 true,相对路径返回 false ---
|
|
474
|
+
* @param path 要判断的路径字符串
|
|
475
|
+
*/
|
|
356
476
|
function isRealPath(path) {
|
|
357
477
|
path = path.replace(/\\/g, '/');
|
|
358
478
|
if (path.startsWith('/')) {
|
|
@@ -360,6 +480,10 @@ function isRealPath(path) {
|
|
|
360
480
|
}
|
|
361
481
|
return /[a-z]+:/i.test(path.split('/')[0]) ? true : false;
|
|
362
482
|
}
|
|
483
|
+
/**
|
|
484
|
+
* --- 获取文件名 ---
|
|
485
|
+
* @param path 文件路径
|
|
486
|
+
*/
|
|
363
487
|
function getFilename(path) {
|
|
364
488
|
path = path.replace(/\\/g, '/');
|
|
365
489
|
const lio = path.lastIndexOf('/');
|
|
@@ -368,8 +492,13 @@ function getFilename(path) {
|
|
|
368
492
|
}
|
|
369
493
|
return path.slice(lio + 1);
|
|
370
494
|
}
|
|
495
|
+
/**
|
|
496
|
+
* --- 将普通的返回 JSON 对象序列化为字符串,Mutton 不能使用 ---
|
|
497
|
+
* @param o 返回 JSON 对象
|
|
498
|
+
*/
|
|
371
499
|
function stringifyResult(rtn) {
|
|
372
500
|
if (Array.isArray(rtn)) {
|
|
501
|
+
// --- [0, 'xxx'] 模式 ---
|
|
373
502
|
if (rtn.length === 0) {
|
|
374
503
|
return JSON.stringify({
|
|
375
504
|
'result': 0,
|
|
@@ -377,14 +506,17 @@ function stringifyResult(rtn) {
|
|
|
377
506
|
});
|
|
378
507
|
}
|
|
379
508
|
if (typeof rtn[0] === 'number') {
|
|
509
|
+
// --- 1. ---
|
|
380
510
|
const json = { 'result': rtn[0] };
|
|
381
511
|
if (rtn[1] !== undefined) {
|
|
382
512
|
if (typeof rtn[1] === 'object') {
|
|
513
|
+
// --- [0, ...{'xx': 'xx'}] ---
|
|
383
514
|
for (let i = 1; i < rtn.length; ++i) {
|
|
384
515
|
Object.assign(json, rtn[i]);
|
|
385
516
|
}
|
|
386
517
|
}
|
|
387
518
|
else {
|
|
519
|
+
// --- [0, 'xxx'], [0, 'xxx', ...{'xx': 'xx'}] ---
|
|
388
520
|
json['msg'] = rtn[1];
|
|
389
521
|
for (let i = 2; i < rtn.length; ++i) {
|
|
390
522
|
Object.assign(json, rtn[i]);
|
|
@@ -393,10 +525,16 @@ function stringifyResult(rtn) {
|
|
|
393
525
|
}
|
|
394
526
|
return JSON.stringify(json);
|
|
395
527
|
}
|
|
528
|
+
// --- 直接是个 json 对象 ---
|
|
396
529
|
return JSON.stringify(rtn);
|
|
397
530
|
}
|
|
531
|
+
// --- 直接是个 json 对象 ---
|
|
398
532
|
return JSON.stringify(rtn);
|
|
399
533
|
}
|
|
534
|
+
/**
|
|
535
|
+
* --- 将字符串解析为对象,返回 false 代表解析失败,支持 BigInt,Kebab true, Mutton false ---
|
|
536
|
+
* @param str 要解析的 json 字符串
|
|
537
|
+
*/
|
|
400
538
|
function parseJson(str) {
|
|
401
539
|
try {
|
|
402
540
|
str = str.replace(/("[\w-]+?" *: *)([-+0-9]+)([ \r\n]*[,}]|$)/g, (v, v1, v2, v3) => {
|
|
@@ -421,6 +559,11 @@ function parseJson(str) {
|
|
|
421
559
|
return false;
|
|
422
560
|
}
|
|
423
561
|
}
|
|
562
|
+
/**
|
|
563
|
+
* --- 将对象转换为 json 字符串,返回 false 代表解析失败,支持 BigInt,Kebab true, Mutton false ---
|
|
564
|
+
* @param obj 要转换的 json 对象
|
|
565
|
+
* @param space 美化方式
|
|
566
|
+
*/
|
|
424
567
|
function stringifyJson(obj, space) {
|
|
425
568
|
return JSON.stringify(obj, (k, v) => {
|
|
426
569
|
if (typeof v === 'bigint') {
|
|
@@ -429,27 +572,72 @@ function stringifyJson(obj, space) {
|
|
|
429
572
|
return v;
|
|
430
573
|
}, space).replace(/"-mybigint-([-+0-9]+?)"/g, '$1');
|
|
431
574
|
}
|
|
575
|
+
/**
|
|
576
|
+
* --- 输出文本格式的 buffer ---
|
|
577
|
+
* @param buf 原始 buffer
|
|
578
|
+
*/
|
|
579
|
+
function stringifyBuffer(buf) {
|
|
580
|
+
const arr = buf.toString('hex').match(/.{1,2}/g);
|
|
581
|
+
return `<Buffer ${arr ? arr.join(' ') : ''}>`;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* --- 判断一个值是否是虚假的(为 null/undefined/空字符串/false/0) ---
|
|
585
|
+
* @param val 要判断的值
|
|
586
|
+
*/
|
|
432
587
|
function isFalsy(val) {
|
|
433
588
|
return (val === null) || (val === undefined) || (val === '') || (val === false) || (val === 0);
|
|
434
589
|
}
|
|
590
|
+
/**
|
|
591
|
+
* --- 类似 || 运算符的效果 ---
|
|
592
|
+
* @param v1 比对值
|
|
593
|
+
* @param v2 比对值
|
|
594
|
+
*/
|
|
435
595
|
function logicalOr(v1, v2) {
|
|
436
596
|
return (isFalsy(v1) ? v2 : v1);
|
|
437
597
|
}
|
|
598
|
+
/**
|
|
599
|
+
* --- 为解决精度问题,将字符串数字转换为整数显示 ---
|
|
600
|
+
* --- 以下几个示例都是当 digits 为 2 时 ---
|
|
601
|
+
* --- str 传入 '1.234',返回 123 ---
|
|
602
|
+
* --- str 传入 '1.235',返回 124 ---
|
|
603
|
+
* --- str 传入 '1.1',返回 110 ---
|
|
604
|
+
* --- str 传入 '6',返回 600 ---
|
|
605
|
+
* @param str 要转换的数字字符串
|
|
606
|
+
* @param digits 小数点右移位数
|
|
607
|
+
*/
|
|
438
608
|
function str2int(str, digits = 3) {
|
|
439
609
|
const num = parseFloat(str);
|
|
610
|
+
/** --- 位数,如 1000 --- */
|
|
440
611
|
const factor = Math.pow(10, digits);
|
|
441
612
|
return Math.round(num * factor);
|
|
442
613
|
}
|
|
614
|
+
/**
|
|
615
|
+
* --- 为解决精度问题,将整数转换为小数字符串 ---
|
|
616
|
+
* --- 以下几个示例都是当 digits 为 3、decimal 为 2 时 ---
|
|
617
|
+
* --- int 传入 2341,返回 '2.34' ---
|
|
618
|
+
* --- int 传入 2345,返回 '2.35' ---
|
|
619
|
+
* --- int 传入 23,返回 '0.02' ---
|
|
620
|
+
* --- int 传入 2,返回 '0.00' ---
|
|
621
|
+
* @param int 要转换的整数
|
|
622
|
+
* @param digits 小数点左移位数
|
|
623
|
+
* @param decimal 最终保留的小数位数
|
|
624
|
+
*/
|
|
443
625
|
function int2str(int, digits = 4, decimal = 2) {
|
|
626
|
+
/** --- 正负符号 --- */
|
|
444
627
|
const sign = int < 0 ? '-' : '';
|
|
445
628
|
const absInt = Math.abs(int);
|
|
446
629
|
let intStr = absInt.toString();
|
|
630
|
+
// --- 补前导零至长度 digits + 1 ---
|
|
447
631
|
while (intStr.length < digits + 1) {
|
|
448
632
|
intStr = '0' + intStr;
|
|
449
633
|
}
|
|
634
|
+
/** --- 整数部分字符串 --- */
|
|
450
635
|
const intPart = intStr.slice(0, intStr.length - digits);
|
|
636
|
+
/** --- 小数部分字符串 --- */
|
|
451
637
|
const decPart = intStr.slice(intStr.length - digits);
|
|
638
|
+
/** --- 小数部分数字 --- */
|
|
452
639
|
const decNum = parseInt(decPart);
|
|
640
|
+
/** --- 要除的数 --- */
|
|
453
641
|
const div = Math.pow(10, digits - decimal);
|
|
454
642
|
const round = Math.round(decNum / div);
|
|
455
643
|
const carry = Math.floor(round / Math.pow(10, decimal));
|
package/lib/time.d.ts
CHANGED
|
@@ -1,22 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project: Kebab, User: JianSuoQiYue
|
|
3
|
+
* Date: 2019-6-6 12:04:15
|
|
4
|
+
* Last: 2020-3-29 23:41:21, 2024-1-18 17:16:50, 2024-8-5 10:55:21
|
|
5
|
+
*/
|
|
1
6
|
import * as sCtr from '../sys/ctr';
|
|
2
7
|
export interface IOptions {
|
|
8
|
+
/** --- 时区 --- */
|
|
3
9
|
'zone'?: number;
|
|
10
|
+
/** --- 字符串、时间戳(秒或毫秒) --- */
|
|
4
11
|
'data'?: string | number;
|
|
5
12
|
}
|
|
13
|
+
/** --- 一小时的秒数 --- */
|
|
6
14
|
export declare const HOUR = 3600;
|
|
15
|
+
/** --- 一天的秒数 --- */
|
|
7
16
|
export declare const DAY = 86400;
|
|
17
|
+
/** --- 一年(365 天) */
|
|
8
18
|
export declare const YEAR = 31536000;
|
|
9
19
|
export declare class Time {
|
|
20
|
+
/** --- 当前 date --- */
|
|
10
21
|
private readonly _date;
|
|
22
|
+
/** --- 当前时区 --- */
|
|
11
23
|
private _zone;
|
|
24
|
+
/**
|
|
25
|
+
* --- 构造函数 ---
|
|
26
|
+
* @param opt
|
|
27
|
+
*/
|
|
12
28
|
constructor(ctr: sCtr.Ctr, opt: IOptions);
|
|
29
|
+
/**
|
|
30
|
+
* --- 设置时区 ---
|
|
31
|
+
* @param zone 北京时间如 8
|
|
32
|
+
*/
|
|
13
33
|
setZone(zone: number): void;
|
|
34
|
+
/**
|
|
35
|
+
* --- 获取时区 ---
|
|
36
|
+
*/
|
|
14
37
|
getZone(): number;
|
|
38
|
+
/**
|
|
39
|
+
* --- 获取 UTC 字符串 ---
|
|
40
|
+
*/
|
|
15
41
|
toUTCString(): string;
|
|
42
|
+
/**
|
|
43
|
+
* --- 获取格式化的字符串 ---
|
|
44
|
+
* @param f 格式化字符串
|
|
45
|
+
* @param zone 时区小时,如 8
|
|
46
|
+
*/
|
|
16
47
|
format(f: string, zone?: number): string;
|
|
48
|
+
/**
|
|
49
|
+
* --- 获取秒级时间戳 ---
|
|
50
|
+
*/
|
|
17
51
|
stamp(): number;
|
|
18
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* --- 创建获取一个时间对象 ---
|
|
55
|
+
* @param opt
|
|
56
|
+
*/
|
|
19
57
|
export declare function get(ctr: sCtr.Ctr, opt?: IOptions): Time;
|
|
58
|
+
/**
|
|
59
|
+
* --- 获取秒级时间戳 ---
|
|
60
|
+
* @param date Date 对象可选
|
|
61
|
+
* @param zone 时区小时或 ctr 对象,如 8,设置 null 则以系统时区为准
|
|
62
|
+
*/
|
|
20
63
|
export declare function stamp(date?: Date | string, zone?: number | sCtr.Ctr | null): number;
|
|
64
|
+
/**
|
|
65
|
+
* --- 是否是毫秒 ---
|
|
66
|
+
* @param time 要判断的时间戳
|
|
67
|
+
*/
|
|
21
68
|
export declare function isMs(time: number): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* --- 将时间对象转换为时间字符串 ---
|
|
71
|
+
* @param zone 时区小时或 ctr 对象,如 8,设置 null 则以系统时区为准
|
|
72
|
+
* @param f 转换格式
|
|
73
|
+
* @param date 时间对象或秒/毫秒级数字,如果是秒请乘以 1000
|
|
74
|
+
*/
|
|
22
75
|
export declare function format(zone: number | sCtr.Ctr | null, f: string, date?: Date | number): string;
|