ph-utils 0.3.0 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +11 -11
- package/lib/crypto_node.d.ts +44 -0
- package/lib/crypto_node.js +88 -0
- package/lib/crypto_ssl.d.ts +56 -0
- package/lib/crypto_ssl.js +232 -0
- package/lib/index.d.ts +0 -14
- package/lib/index.js +0 -33
- package/lib/web.d.ts +14 -0
- package/lib/web.js +33 -0
- package/package.json +1 -1
package/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
## ph-utils
|
2
|
-
|
3
|
-
整理了 js 前后端开发(web + nodejs)时常用的一些工具;[详细文档](https://gitee.com/towardly/ph/wikis/Home?sort_id=4035190)
|
4
|
-
|
5
|
-
### 后端(node server)
|
6
|
-
|
7
|
-
包含了一些 node 后端开发(web server) 时常用的工具类,包括 `index` 基础工具类(这个类里面的函数同样也适用于前端)、`date` 跟日期相关的工具类、`file` 文件操作相关工具类、`server` 一些只适用于后端的工具(使用了后端的 API 列表)、`validator` 数据验证
|
8
|
-
|
9
|
-
### 前端(web)
|
10
|
-
|
11
|
-
包含了一些前端网站开发时常用的工具类,包括 `index` 基础工具类(这个类里面的函数同样也适用于前端)、`date` 跟日期相关的工具类、`dom` 浏览器节点操作相关、`web` 一些只适用于前端相关的工具、`validator` 数据验证
|
1
|
+
## ph-utils
|
2
|
+
|
3
|
+
整理了 js 前后端开发(web + nodejs)时常用的一些工具;[详细文档](https://gitee.com/towardly/ph/wikis/Home?sort_id=4035190)
|
4
|
+
|
5
|
+
### 后端(node server)
|
6
|
+
|
7
|
+
包含了一些 node 后端开发(web server) 时常用的工具类,包括 `index` 基础工具类(这个类里面的函数同样也适用于前端)、`date` 跟日期相关的工具类、`file` 文件操作相关工具类、`server` 一些只适用于后端的工具(使用了后端的 API 列表)、`validator` 数据验证
|
8
|
+
|
9
|
+
### 前端(web)
|
10
|
+
|
11
|
+
包含了一些前端网站开发时常用的工具类,包括 `index` 基础工具类(这个类里面的函数同样也适用于前端)、`date` 跟日期相关的工具类、`dom` 浏览器节点操作相关、`web` 一些只适用于前端相关的工具、`validator` 数据验证
|
@@ -0,0 +1,44 @@
|
|
1
|
+
type HashAlgorithmName = 'md5' | 'sha1' | 'sha256';
|
2
|
+
/**
|
3
|
+
* 进行 md5|sha1|sha256 数据摘要签名
|
4
|
+
* @param d 待加密的数据
|
5
|
+
* @param algorithm 签名算法, md5、sha1. Defaults to "md5".
|
6
|
+
* @param upper 返回的结果是否需要大写. Defaults to False.
|
7
|
+
*/
|
8
|
+
export declare function hashDigest(d: string, algorithm?: HashAlgorithmName, upper?: boolean): string;
|
9
|
+
/**
|
10
|
+
* 生成 RSA 签名密钥对
|
11
|
+
* @returns: [公钥, 私钥]
|
12
|
+
*/
|
13
|
+
export declare function keyPair(): Promise<[string, string]>;
|
14
|
+
/**
|
15
|
+
* AES 加密
|
16
|
+
* @param key 加密密钥
|
17
|
+
* @param input 待加密的数据
|
18
|
+
* @param upper 是否转换为大写
|
19
|
+
* @returns [加密数据, 向量]
|
20
|
+
*/
|
21
|
+
export declare function aesEncrypt(key: string, input: string, upper?: boolean): [string, string];
|
22
|
+
/**
|
23
|
+
* AES 解密
|
24
|
+
* @param input 加密后的数据
|
25
|
+
* @param key 密钥
|
26
|
+
* @param iv 向量
|
27
|
+
* @returns
|
28
|
+
*/
|
29
|
+
export declare function aesDecrypt(input: string, key: string, iv: string): string;
|
30
|
+
/**
|
31
|
+
* RSA 公钥加密
|
32
|
+
* @param input 待加密字符串
|
33
|
+
* @param publicKey 公钥
|
34
|
+
* @returns
|
35
|
+
*/
|
36
|
+
export declare function rsaEncrypt(input: string, publicKey: string): string;
|
37
|
+
/**
|
38
|
+
* RSA 解密
|
39
|
+
* @param encrtypData RSA加密后的数据
|
40
|
+
* @param privateKey 私钥
|
41
|
+
* @returns
|
42
|
+
*/
|
43
|
+
export declare function rsaDecrypt(encrtypData: string, privateKey: string): string;
|
44
|
+
export {};
|
@@ -0,0 +1,88 @@
|
|
1
|
+
import { createHash, createCipheriv, randomBytes, generateKeyPair, createDecipheriv, privateDecrypt, publicEncrypt, } from 'node:crypto';
|
2
|
+
/**
|
3
|
+
* 进行 md5|sha1|sha256 数据摘要签名
|
4
|
+
* @param d 待加密的数据
|
5
|
+
* @param algorithm 签名算法, md5、sha1. Defaults to "md5".
|
6
|
+
* @param upper 返回的结果是否需要大写. Defaults to False.
|
7
|
+
*/
|
8
|
+
export function hashDigest(d, algorithm = 'sha256', upper = false) {
|
9
|
+
const hashed = createHash(algorithm).update(d).digest('hex');
|
10
|
+
return upper ? hashed.toUpperCase() : hashed;
|
11
|
+
}
|
12
|
+
/**
|
13
|
+
* 生成 RSA 签名密钥对
|
14
|
+
* @returns: [公钥, 私钥]
|
15
|
+
*/
|
16
|
+
export async function keyPair() {
|
17
|
+
return new Promise((resolve, reject) => {
|
18
|
+
generateKeyPair('rsa', {
|
19
|
+
modulusLength: 2048,
|
20
|
+
publicKeyEncoding: {
|
21
|
+
type: 'spki',
|
22
|
+
format: 'pem',
|
23
|
+
},
|
24
|
+
privateKeyEncoding: {
|
25
|
+
type: 'pkcs8',
|
26
|
+
format: 'pem',
|
27
|
+
},
|
28
|
+
}, (err, publicKey, privateKey) => {
|
29
|
+
if (err == null) {
|
30
|
+
resolve([publicKey, privateKey]);
|
31
|
+
}
|
32
|
+
else {
|
33
|
+
reject(err);
|
34
|
+
}
|
35
|
+
});
|
36
|
+
});
|
37
|
+
}
|
38
|
+
/**
|
39
|
+
* AES 加密
|
40
|
+
* @param key 加密密钥
|
41
|
+
* @param input 待加密的数据
|
42
|
+
* @param upper 是否转换为大写
|
43
|
+
* @returns [加密数据, 向量]
|
44
|
+
*/
|
45
|
+
export function aesEncrypt(key, input, upper = false) {
|
46
|
+
const iv = randomBytes(16);
|
47
|
+
const cipher = createCipheriv('aes-256-cbc', Buffer.from(key, 'hex'), iv);
|
48
|
+
let encryptedData = cipher.update(input, 'utf-8', 'hex');
|
49
|
+
encryptedData += cipher.final('hex');
|
50
|
+
return [upper === true ? encryptedData.toUpperCase() : encryptedData, iv.toString('hex')];
|
51
|
+
}
|
52
|
+
/**
|
53
|
+
* AES 解密
|
54
|
+
* @param input 加密后的数据
|
55
|
+
* @param key 密钥
|
56
|
+
* @param iv 向量
|
57
|
+
* @returns
|
58
|
+
*/
|
59
|
+
export function aesDecrypt(input, key, iv) {
|
60
|
+
const cipher = createDecipheriv('aes-256-cbc', Buffer.from(key, 'hex'), Buffer.from(iv, 'hex'));
|
61
|
+
let decryptedData = cipher.update(input, 'hex', 'utf-8');
|
62
|
+
decryptedData += cipher.final('utf-8');
|
63
|
+
return decryptedData;
|
64
|
+
}
|
65
|
+
/**
|
66
|
+
* RSA 公钥加密
|
67
|
+
* @param input 待加密字符串
|
68
|
+
* @param publicKey 公钥
|
69
|
+
* @returns
|
70
|
+
*/
|
71
|
+
export function rsaEncrypt(input, publicKey) {
|
72
|
+
return publicEncrypt({
|
73
|
+
key: publicKey,
|
74
|
+
oaepHash: 'sha256',
|
75
|
+
}, Buffer.from(input)).toString('base64');
|
76
|
+
}
|
77
|
+
/**
|
78
|
+
* RSA 解密
|
79
|
+
* @param encrtypData RSA加密后的数据
|
80
|
+
* @param privateKey 私钥
|
81
|
+
* @returns
|
82
|
+
*/
|
83
|
+
export function rsaDecrypt(encrtypData, privateKey) {
|
84
|
+
return privateDecrypt({
|
85
|
+
key: privateKey,
|
86
|
+
oaepHash: 'sha256',
|
87
|
+
}, Buffer.from(encrtypData, 'base64')).toString('utf-8');
|
88
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
/**
|
2
|
+
* 将原始的二进制数据转换为 Hex String
|
3
|
+
* @param bf 待转换的原始数据
|
4
|
+
* @param upper 是否需要转换为大写
|
5
|
+
* @returns
|
6
|
+
*/
|
7
|
+
export declare function bufferToHex(bf: ArrayBuffer | Uint8Array, upper?: boolean): string;
|
8
|
+
/**
|
9
|
+
* SHA 哈希算法
|
10
|
+
* @param message 待进行 hash 的数据
|
11
|
+
* @param upper 是否转换为大写, 默认为: false
|
12
|
+
* @param algorithm hash算法, 支持: SHA-1、SHA-256、SHA-384、SHA-512; 默认为: SHA-256
|
13
|
+
* @returns
|
14
|
+
*/
|
15
|
+
export declare function sha(message: string, upper?: boolean, algorithm?: string): Promise<string>;
|
16
|
+
/** 返回结果类似 */
|
17
|
+
type AlgorithmResType = 'hex' | 'hexUpper' | 'base64' | 'raw';
|
18
|
+
/**
|
19
|
+
* AES 加密
|
20
|
+
* @param message 待加密的数据
|
21
|
+
* @param key 加解密密钥
|
22
|
+
* @param encode 加密后的数据转换的形式, hex - 转换为16进制字符串, hexUpper - 转换为16进制且大写, base64 - 转换为 base64 形式
|
23
|
+
* @param iv 加解密向量
|
24
|
+
* @returns [加密数据,向量]
|
25
|
+
*/
|
26
|
+
export declare function aesEncrypt(message: string, key: string, encode?: AlgorithmResType, iv?: null | Uint8Array | string): Promise<{
|
27
|
+
ciphertext: string | ArrayBuffer;
|
28
|
+
iv: string;
|
29
|
+
key: string;
|
30
|
+
}>;
|
31
|
+
/**
|
32
|
+
* AES 解密
|
33
|
+
* @param message 加密后的数据
|
34
|
+
* @param key 解密密钥
|
35
|
+
* @param iv 向量
|
36
|
+
* @param encode 加密后数据的形式: hex | base64
|
37
|
+
* @returns
|
38
|
+
*/
|
39
|
+
export declare function aesDecrypt(message: Uint8Array | string, key: string, iv: string, encode?: AlgorithmResType): Promise<string>;
|
40
|
+
/**
|
41
|
+
* RSA 加密
|
42
|
+
* @param key 公钥
|
43
|
+
* @param message 待加密数据
|
44
|
+
* @param encode 返回类型
|
45
|
+
* @returns
|
46
|
+
*/
|
47
|
+
export declare function rsaEncrypt(message: string, publicKey: string, encode?: AlgorithmResType): Promise<string | ArrayBuffer>;
|
48
|
+
/**
|
49
|
+
* RSA 解密
|
50
|
+
* @param key 私钥, 根据私钥解密
|
51
|
+
* @param message 加密后的数据
|
52
|
+
* @param encode 加密后的数据形式
|
53
|
+
* @returns
|
54
|
+
*/
|
55
|
+
export declare function rsaDecrypt(privateKey: string, message: Uint8Array | string, encode?: AlgorithmResType): Promise<string>;
|
56
|
+
export {};
|
@@ -0,0 +1,232 @@
|
|
1
|
+
/* eslint-disable no-undef */
|
2
|
+
/**
|
3
|
+
* 将原始的二进制数据转换为 Hex String
|
4
|
+
* @param bf 待转换的原始数据
|
5
|
+
* @param upper 是否需要转换为大写
|
6
|
+
* @returns
|
7
|
+
*/
|
8
|
+
export function bufferToHex(bf, upper = false) {
|
9
|
+
const u8Array = bf instanceof Uint8Array ? bf : new Uint8Array(bf);
|
10
|
+
const hashArray = Array.from(u8Array);
|
11
|
+
return hashArray
|
12
|
+
.map((b) => {
|
13
|
+
let hx = b.toString(16).padStart(2, '0');
|
14
|
+
return upper === true ? hx.toUpperCase() : hx;
|
15
|
+
})
|
16
|
+
.join('');
|
17
|
+
}
|
18
|
+
/**
|
19
|
+
* 将16进制的数据转换为 UInt8Array
|
20
|
+
* @param data 16进制的数据
|
21
|
+
* @returns
|
22
|
+
*/
|
23
|
+
function hexToBuffer(data) {
|
24
|
+
const len = data.length / 2;
|
25
|
+
const uint8Array = new Uint8Array(len);
|
26
|
+
for (let i = 0; i < len; i++) {
|
27
|
+
const byteHex = data.substring(i * 2, i * 2 + 2);
|
28
|
+
const byte = parseInt(byteHex.toLocaleLowerCase(), 16);
|
29
|
+
uint8Array[i] = byte;
|
30
|
+
}
|
31
|
+
return uint8Array;
|
32
|
+
}
|
33
|
+
/**
|
34
|
+
* 将原始数据转换为 Base64 编码
|
35
|
+
* @param bf 待转换的原始数据
|
36
|
+
* @returns
|
37
|
+
*/
|
38
|
+
function bufferToBase64(bf) {
|
39
|
+
const u8Array = bf instanceof Uint8Array ? bf : new Uint8Array(bf);
|
40
|
+
const hashArray = Array.from(u8Array);
|
41
|
+
return window.btoa(String.fromCharCode.apply(null, hashArray));
|
42
|
+
}
|
43
|
+
/**
|
44
|
+
* 将 Base64 转换为 UInt8Array 数据
|
45
|
+
* @param data
|
46
|
+
* @returns
|
47
|
+
*/
|
48
|
+
function base64ToBuffer(data) {
|
49
|
+
return new Uint8Array(window
|
50
|
+
.atob(data)
|
51
|
+
.split('')
|
52
|
+
.map((char) => char.charCodeAt(0)));
|
53
|
+
}
|
54
|
+
/**
|
55
|
+
* SHA 哈希算法
|
56
|
+
* @param message 待进行 hash 的数据
|
57
|
+
* @param upper 是否转换为大写, 默认为: false
|
58
|
+
* @param algorithm hash算法, 支持: SHA-1、SHA-256、SHA-384、SHA-512; 默认为: SHA-256
|
59
|
+
* @returns
|
60
|
+
*/
|
61
|
+
export async function sha(message, upper = false, algorithm = 'SHA-256') {
|
62
|
+
const msgUint8 = new TextEncoder().encode(message);
|
63
|
+
const hashBuffer = await window.crypto.subtle.digest(algorithm || 'SHA-256', msgUint8);
|
64
|
+
return bufferToHex(hashBuffer, upper);
|
65
|
+
}
|
66
|
+
function parseRsaKey(pem) {
|
67
|
+
const pemHeader = '-----BEGIN PUBLIC KEY-----';
|
68
|
+
const pemFooter = '-----END PUBLIC KEY-----';
|
69
|
+
if (pem.indexOf(pemHeader) !== -1 && pem.indexOf(pemFooter) !== -1) {
|
70
|
+
pem = pem.substring(pemHeader.length, pem.indexOf(pemFooter)).trim();
|
71
|
+
}
|
72
|
+
return pem;
|
73
|
+
}
|
74
|
+
/**
|
75
|
+
* 导入上下文密钥
|
76
|
+
* @param key 导入的密钥
|
77
|
+
* @param algorithmName 算法名称
|
78
|
+
* @param usages 该密钥可以用于哪些函数使用
|
79
|
+
* @returns
|
80
|
+
*/
|
81
|
+
// eslint-disable-next-line no-undef
|
82
|
+
async function importKey(key, algorithmName, usages, encoding = 'hex') {
|
83
|
+
let name = 'AES-CBC';
|
84
|
+
if (algorithmName == null) {
|
85
|
+
name = 'AES-CBC';
|
86
|
+
}
|
87
|
+
else {
|
88
|
+
if (algorithmName.toUpperCase() === 'AES') {
|
89
|
+
name = 'AES-CBC';
|
90
|
+
}
|
91
|
+
else if (algorithmName.toUpperCase() === 'RSA') {
|
92
|
+
name = 'RSA-OAEP';
|
93
|
+
}
|
94
|
+
}
|
95
|
+
name = name.toUpperCase();
|
96
|
+
if (usages == null || usages.length === 0) {
|
97
|
+
usages = ['encrypt'];
|
98
|
+
}
|
99
|
+
let format = 'raw';
|
100
|
+
let algorithm = { name };
|
101
|
+
if (name.includes('RSA')) {
|
102
|
+
format = 'spki';
|
103
|
+
algorithm.hash = { name: 'SHA-256' };
|
104
|
+
key = parseRsaKey(key);
|
105
|
+
}
|
106
|
+
const keyBuf = encoding === 'base64' ? base64ToBuffer(key) : hexToBuffer(key);
|
107
|
+
// importKey时传 false 表明该密钥不能被导出
|
108
|
+
return Promise.all([
|
109
|
+
window.crypto.subtle.importKey(format, keyBuf, algorithm, false, usages),
|
110
|
+
Promise.resolve({ name }),
|
111
|
+
]);
|
112
|
+
}
|
113
|
+
/**
|
114
|
+
* 加密
|
115
|
+
* @param algorithm 算法参数, 算法名称、向量等
|
116
|
+
* @param key 算法密钥
|
117
|
+
* @param message 待加密的数据
|
118
|
+
* @param encode 解密后返回数据格式
|
119
|
+
* @returns
|
120
|
+
*/
|
121
|
+
async function encrypt(algorithm, key, message, encode = 'hex') {
|
122
|
+
if (typeof message === 'string') {
|
123
|
+
message = new TextEncoder().encode(message);
|
124
|
+
}
|
125
|
+
const encrypted = await window.crypto.subtle.encrypt(algorithm, key, message);
|
126
|
+
if (encode === 'hex') {
|
127
|
+
return bufferToHex(encrypted);
|
128
|
+
}
|
129
|
+
else if (encode === 'hexUpper') {
|
130
|
+
return bufferToHex(encrypted, true);
|
131
|
+
}
|
132
|
+
else if (encode === 'base64') {
|
133
|
+
return bufferToBase64(encrypted);
|
134
|
+
}
|
135
|
+
else {
|
136
|
+
return encrypted;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
/**
|
140
|
+
* 数据解密
|
141
|
+
* @param algorithm 解密算法
|
142
|
+
* @param key 解密密钥
|
143
|
+
* @param message 加密后的数据
|
144
|
+
* @returns
|
145
|
+
*/
|
146
|
+
async function decrypt(algorithm, key, message) {
|
147
|
+
const decrypted = await window.crypto.subtle.decrypt(algorithm, key, message);
|
148
|
+
return new TextDecoder('utf-8').decode(decrypted);
|
149
|
+
}
|
150
|
+
/**
|
151
|
+
* AES 加密
|
152
|
+
* @param message 待加密的数据
|
153
|
+
* @param key 加解密密钥
|
154
|
+
* @param encode 加密后的数据转换的形式, hex - 转换为16进制字符串, hexUpper - 转换为16进制且大写, base64 - 转换为 base64 形式
|
155
|
+
* @param iv 加解密向量
|
156
|
+
* @returns [加密数据,向量]
|
157
|
+
*/
|
158
|
+
export async function aesEncrypt(message, key, encode = 'hex', iv = null) {
|
159
|
+
let ciphertext = '';
|
160
|
+
let resIv = '';
|
161
|
+
// 导入密钥
|
162
|
+
const [cryptoKey, algorithm] = await importKey(key, 'aes', ['encrypt']);
|
163
|
+
if (iv == null) {
|
164
|
+
iv = window.crypto.getRandomValues(new Uint8Array(16));
|
165
|
+
}
|
166
|
+
else if (typeof iv === 'string') {
|
167
|
+
iv = hexToBuffer(iv);
|
168
|
+
}
|
169
|
+
const encodeData = await encrypt({ ...algorithm, iv }, cryptoKey, message, encode);
|
170
|
+
ciphertext = encodeData;
|
171
|
+
resIv = bufferToHex(iv);
|
172
|
+
return { ciphertext, iv: resIv, key };
|
173
|
+
}
|
174
|
+
/**
|
175
|
+
* 根据加密后的数据类型使用对应函数最终转换为 UInt8Array
|
176
|
+
* @param message 原始加密后的数据
|
177
|
+
* @param type 类型: hex | base64
|
178
|
+
* @returns
|
179
|
+
*/
|
180
|
+
function parseEncryptData(message, type) {
|
181
|
+
let input;
|
182
|
+
if (typeof message === 'string') {
|
183
|
+
if (type === 'hex' || type === 'hexUpper') {
|
184
|
+
input = hexToBuffer(message);
|
185
|
+
}
|
186
|
+
else {
|
187
|
+
input = base64ToBuffer(message);
|
188
|
+
}
|
189
|
+
}
|
190
|
+
else {
|
191
|
+
input = message;
|
192
|
+
}
|
193
|
+
return input;
|
194
|
+
}
|
195
|
+
/**
|
196
|
+
* AES 解密
|
197
|
+
* @param message 加密后的数据
|
198
|
+
* @param key 解密密钥
|
199
|
+
* @param iv 向量
|
200
|
+
* @param encode 加密后数据的形式: hex | base64
|
201
|
+
* @returns
|
202
|
+
*/
|
203
|
+
export async function aesDecrypt(message, key, iv, encode = 'hex') {
|
204
|
+
// 导入密钥
|
205
|
+
const [cryptoKey, algorithm] = await importKey(key, 'aes', ['decrypt']);
|
206
|
+
const input = parseEncryptData(message, encode);
|
207
|
+
return await decrypt({ ...algorithm, iv: hexToBuffer(iv) }, cryptoKey, input);
|
208
|
+
}
|
209
|
+
/**
|
210
|
+
* RSA 加密
|
211
|
+
* @param key 公钥
|
212
|
+
* @param message 待加密数据
|
213
|
+
* @param encode 返回类型
|
214
|
+
* @returns
|
215
|
+
*/
|
216
|
+
export async function rsaEncrypt(message, publicKey, encode = 'hex') {
|
217
|
+
// 导入密钥
|
218
|
+
const [cryptoKey, algorithm] = await importKey(publicKey, 'rsa', ['encrypt'], 'base64');
|
219
|
+
return await encrypt(algorithm, cryptoKey, message, encode);
|
220
|
+
}
|
221
|
+
/**
|
222
|
+
* RSA 解密
|
223
|
+
* @param key 私钥, 根据私钥解密
|
224
|
+
* @param message 加密后的数据
|
225
|
+
* @param encode 加密后的数据形式
|
226
|
+
* @returns
|
227
|
+
*/
|
228
|
+
export async function rsaDecrypt(privateKey, message, encode = 'hex') {
|
229
|
+
// 导入密钥
|
230
|
+
const [cryptoKey, algorithm] = await importKey(privateKey, 'rsa', ['decrypt']);
|
231
|
+
return await decrypt({ ...algorithm }, cryptoKey, parseEncryptData(message, encode));
|
232
|
+
}
|
package/lib/index.d.ts
CHANGED
@@ -74,20 +74,6 @@ export declare class BaseError extends Error {
|
|
74
74
|
*/
|
75
75
|
constructor(name: string, message: string);
|
76
76
|
}
|
77
|
-
/**
|
78
|
-
* 函数节流 - 每隔单位时间,只执行一次
|
79
|
-
* @param cb 待节流的函数
|
80
|
-
* @param wait 间隔时间
|
81
|
-
* @returns
|
82
|
-
*/
|
83
|
-
export declare function throttle<R extends any[], T>(fn: (...args: R) => T, wait?: number): (...args: R) => void;
|
84
|
-
/**
|
85
|
-
* 函数防抖 - 当重复触发某一个行为(事件时),只执行最后一次触发
|
86
|
-
* @param fn 防抖函数
|
87
|
-
* @param interval 间隔时间段
|
88
|
-
* @returns
|
89
|
-
*/
|
90
|
-
export declare function debounce<R extends any[], T>(fn: (...args: R) => T, interval?: number): (...args: R) => void;
|
91
77
|
/**
|
92
78
|
* 将金额数字格式化为金额格式显示并且会保留两位小数[去除多余的位数,不是四舍五入,而是直接舍去] 1234523432.23 => 123,123,123.23
|
93
79
|
* @param {number} number 待转换的金额数字
|
package/lib/index.js
CHANGED
@@ -108,39 +108,6 @@ export class BaseError extends Error {
|
|
108
108
|
}
|
109
109
|
}
|
110
110
|
}
|
111
|
-
/**
|
112
|
-
* 函数节流 - 每隔单位时间,只执行一次
|
113
|
-
* @param cb 待节流的函数
|
114
|
-
* @param wait 间隔时间
|
115
|
-
* @returns
|
116
|
-
*/
|
117
|
-
export function throttle(fn, wait = 500) {
|
118
|
-
// 上一次的请求时间
|
119
|
-
let last = 0;
|
120
|
-
return (...args) => {
|
121
|
-
// 当前时间戳
|
122
|
-
const now = Date.now();
|
123
|
-
if (now - last > wait) {
|
124
|
-
fn(...args);
|
125
|
-
last = now;
|
126
|
-
}
|
127
|
-
};
|
128
|
-
}
|
129
|
-
/**
|
130
|
-
* 函数防抖 - 当重复触发某一个行为(事件时),只执行最后一次触发
|
131
|
-
* @param fn 防抖函数
|
132
|
-
* @param interval 间隔时间段
|
133
|
-
* @returns
|
134
|
-
*/
|
135
|
-
export function debounce(fn, interval = 500) {
|
136
|
-
let _t = -1;
|
137
|
-
return (...args) => {
|
138
|
-
clearTimeout(_t);
|
139
|
-
_t = setTimeout(() => {
|
140
|
-
fn(...args);
|
141
|
-
}, interval);
|
142
|
-
};
|
143
|
-
}
|
144
111
|
/**
|
145
112
|
* 将金额数字格式化为金额格式显示并且会保留两位小数[去除多余的位数,不是四舍五入,而是直接舍去] 1234523432.23 => 123,123,123.23
|
146
113
|
* @param {number} number 待转换的金额数字
|
package/lib/web.d.ts
CHANGED
@@ -11,3 +11,17 @@ export declare const formJson: <T>(form: HTMLFormElement) => T;
|
|
11
11
|
export declare function query(search?: string): {
|
12
12
|
[index: string]: string;
|
13
13
|
};
|
14
|
+
/**
|
15
|
+
* 函数节流 - 每隔单位时间,只执行一次
|
16
|
+
* @param cb 待节流的函数
|
17
|
+
* @param wait 间隔时间
|
18
|
+
* @returns
|
19
|
+
*/
|
20
|
+
export declare function throttle<R extends any[], T>(fn: (...args: R) => T, wait?: number): (...args: R) => void;
|
21
|
+
/**
|
22
|
+
* 函数防抖 - 当重复触发某一个行为(事件时),只执行最后一次触发
|
23
|
+
* @param fn 防抖函数
|
24
|
+
* @param interval 间隔时间段
|
25
|
+
* @returns
|
26
|
+
*/
|
27
|
+
export declare function debounce<R extends any[], T>(fn: (...args: R) => T, interval?: number): (...args: R) => void;
|
package/lib/web.js
CHANGED
@@ -55,3 +55,36 @@ export function query(search) {
|
|
55
55
|
}
|
56
56
|
return query;
|
57
57
|
}
|
58
|
+
/**
|
59
|
+
* 函数节流 - 每隔单位时间,只执行一次
|
60
|
+
* @param cb 待节流的函数
|
61
|
+
* @param wait 间隔时间
|
62
|
+
* @returns
|
63
|
+
*/
|
64
|
+
export function throttle(fn, wait = 500) {
|
65
|
+
// 上一次的请求时间
|
66
|
+
let last = 0;
|
67
|
+
return (...args) => {
|
68
|
+
// 当前时间戳
|
69
|
+
const now = Date.now();
|
70
|
+
if (now - last > wait) {
|
71
|
+
fn(...args);
|
72
|
+
last = now;
|
73
|
+
}
|
74
|
+
};
|
75
|
+
}
|
76
|
+
/**
|
77
|
+
* 函数防抖 - 当重复触发某一个行为(事件时),只执行最后一次触发
|
78
|
+
* @param fn 防抖函数
|
79
|
+
* @param interval 间隔时间段
|
80
|
+
* @returns
|
81
|
+
*/
|
82
|
+
export function debounce(fn, interval = 500) {
|
83
|
+
let _t = -1;
|
84
|
+
return (...args) => {
|
85
|
+
clearTimeout(_t);
|
86
|
+
_t = setTimeout(() => {
|
87
|
+
fn(...args);
|
88
|
+
}, interval);
|
89
|
+
};
|
90
|
+
}
|