ph-utils 0.15.4 → 0.16.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/color.d.ts +5 -4
- package/lib/color.js +0 -1
- package/lib/dom.d.ts +3 -3
- package/lib/dom.js +8 -6
- package/lib/id.d.ts +66 -0
- package/lib/id.js +170 -0
- package/lib/validator.js +11 -6
- package/package.json +1 -1
package/lib/color.d.ts
CHANGED
@@ -9,6 +9,7 @@ type HSVColorObject = {
|
|
9
9
|
s: number;
|
10
10
|
v: number;
|
11
11
|
};
|
12
|
+
type ColorType = string | RGBColorObject | HSVColorObject;
|
12
13
|
/**
|
13
14
|
* 将输入的颜色值转换为RGB对象格式。
|
14
15
|
*
|
@@ -16,14 +17,14 @@ type HSVColorObject = {
|
|
16
17
|
* @returns 返回一个包含r、g、b和a(透明度)属性的RGB对象。
|
17
18
|
* @throws 如果输入的字符串不是有效的颜色表示,则抛出错误。
|
18
19
|
*/
|
19
|
-
export declare function toRgb(color:
|
20
|
+
export declare function toRgb(color: ColorType): RGBColorObject;
|
20
21
|
/**
|
21
22
|
* 将颜色转换为HSV颜色模型。
|
22
23
|
*
|
23
24
|
* @param color - 字符串或者RGB对象
|
24
25
|
* @returns 返回一个包含h、s、v属性的对象,代表HSV颜色值,其中h是色相(取值范围0到360),s是饱和度(取值范围0到1),v是明度(取值范围0到1)。
|
25
26
|
*/
|
26
|
-
export declare function toHsv(color:
|
27
|
+
export declare function toHsv(color: ColorType): HSVColorObject;
|
27
28
|
/**
|
28
29
|
* 将RGB颜色对象转换为十六进制颜色字符串。
|
29
30
|
* @param rgb - 包含红色(r), 绿色(g), 蓝色(b)成分的对象。
|
@@ -35,7 +36,7 @@ export declare function rgbToHex(rgb: RGBColorObject): string;
|
|
35
36
|
* @param color - 颜色, 可以 rgb(0,0,0),rgba(0,0,0,0)字符串, 也可以是 rgb、hsv对象
|
36
37
|
* @returns 返回颜色的十六进制字符串,例如"#FF0000"
|
37
38
|
*/
|
38
|
-
export declare function toHex(color:
|
39
|
+
export declare function toHex(color: ColorType): string;
|
39
40
|
/**
|
40
41
|
* 调整给定颜色深[darken]浅[lighten]
|
41
42
|
* @param color - 输入的颜色,可以是任意颜色表示方式
|
@@ -50,5 +51,5 @@ export declare function toHex(color: any): string;
|
|
50
51
|
*
|
51
52
|
* @returns 返回调整后颜色的十六进制字符串表示。
|
52
53
|
*/
|
53
|
-
export declare function adjust(color:
|
54
|
+
export declare function adjust(color: ColorType, level?: number, light?: boolean): string;
|
54
55
|
export {};
|
package/lib/color.js
CHANGED
package/lib/dom.d.ts
CHANGED
@@ -48,7 +48,7 @@ export declare function $$(tag: string, option?: {
|
|
48
48
|
* @param dom - 可选的父级 DOM 元素,默认为当前文档。
|
49
49
|
* @returns 返回匹配的第一个 HTMLElement,如果没有找到则返回 undefined。
|
50
50
|
*/
|
51
|
-
export declare function $one(selector: string | HTMLElement, dom?: DocumentContext): HTMLElement |
|
51
|
+
export declare function $one(selector: string | HTMLElement, dom?: DocumentContext): HTMLElement | null;
|
52
52
|
/**
|
53
53
|
* 为节点添加 class
|
54
54
|
* @param {HTMLElement} elem 待添加 class 的节点
|
@@ -120,7 +120,7 @@ export declare function html(element: HTMLElement, htmlstr?: string): string | u
|
|
120
120
|
*/
|
121
121
|
export declare function text(element: HTMLElement, textstr?: string): string | null | undefined;
|
122
122
|
export declare function iterate<T>(elems: T[], fn: (el: T, index: number) => any): void;
|
123
|
-
export declare function iterate(elems: NodeList | HTMLCollection
|
123
|
+
export declare function iterate(elems: NodeList | HTMLCollection | NodeListOf<HTMLElement>, fn: (el: HTMLElement, index: number) => any): void;
|
124
124
|
/**
|
125
125
|
* 设置或获取节点 data-* 属性
|
126
126
|
* @param elem
|
@@ -155,7 +155,7 @@ export declare function parent(el: HTMLElement): HTMLElement;
|
|
155
155
|
* @param parent - 添加临时节点的父节点, 如果传递 null, 则通过修改原始样式方式计算,默认为: body.
|
156
156
|
* @returns The DOMRect of the element.
|
157
157
|
*/
|
158
|
-
export declare function queryHideNodeSize(hideNode: string | HTMLElement, parent?: HTMLElement): {
|
158
|
+
export declare function queryHideNodeSize(hideNode: string | HTMLElement, parent?: null | HTMLElement): {
|
159
159
|
width: number;
|
160
160
|
height: number;
|
161
161
|
};
|
package/lib/dom.js
CHANGED
@@ -78,8 +78,10 @@ export function $$(tag, option = {}, ctx) {
|
|
78
78
|
* @returns 返回匹配的第一个 HTMLElement,如果没有找到则返回 undefined。
|
79
79
|
*/
|
80
80
|
export function $one(selector, dom) {
|
81
|
-
|
82
|
-
|
81
|
+
if (typeof selector === "string") {
|
82
|
+
return (dom || document).querySelector(selector);
|
83
|
+
}
|
84
|
+
return selector;
|
83
85
|
}
|
84
86
|
/**
|
85
87
|
* 为节点添加 class
|
@@ -294,9 +296,9 @@ export function queryHideNodeSize(hideNode, parent = document.body) {
|
|
294
296
|
const originalVisibility = hideNode.style.visibility;
|
295
297
|
const originalPosition = hideNode.style.position;
|
296
298
|
// 设置为可见但不可见状态,不影响布局
|
297
|
-
hideNode.style.display = "block";
|
298
|
-
hideNode.style.visibility = "hidden";
|
299
299
|
hideNode.style.position = "absolute";
|
300
|
+
hideNode.style.visibility = "hidden";
|
301
|
+
hideNode.style.display = "block";
|
300
302
|
// 读取高度
|
301
303
|
const rect = hideNode.getBoundingClientRect();
|
302
304
|
// 恢复原样式
|
@@ -317,9 +319,9 @@ export function queryHideNodeSize(hideNode, parent = document.body) {
|
|
317
319
|
$tmpInner.appendChild(hideNode.cloneNode(true));
|
318
320
|
}
|
319
321
|
$tmp.appendChild($tmpInner);
|
320
|
-
parent.appendChild($tmp);
|
322
|
+
(parent || document.body).appendChild($tmp);
|
321
323
|
let rect = $tmpInner.children[0].getBoundingClientRect();
|
322
|
-
parent.removeChild($tmp);
|
324
|
+
(parent || document.body).removeChild($tmp);
|
323
325
|
return { width: rect.width, height: rect.height };
|
324
326
|
}
|
325
327
|
/**
|
package/lib/id.d.ts
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
/** 雪花ID, 推荐在全局构造一个对象用于生成id */
|
2
|
+
export declare class SnowflakeID {
|
3
|
+
/** 机器码, 默认为: 1 */
|
4
|
+
machineId: bigint;
|
5
|
+
/** 起始时间戳, 默认为:1288834974657 */
|
6
|
+
epoch: bigint;
|
7
|
+
_lastTimestamp: bigint;
|
8
|
+
/** 版本号, 默认为: 0 */
|
9
|
+
version: number;
|
10
|
+
private _sequence;
|
11
|
+
/**
|
12
|
+
* 构造函数
|
13
|
+
*
|
14
|
+
* @param machineId 机器标识,默认为1
|
15
|
+
* @param epoch 时间戳起始值,默认为1288834974657
|
16
|
+
*/
|
17
|
+
constructor(machineId?: number, epoch?: number);
|
18
|
+
private _getTimestamp;
|
19
|
+
private _waitNextMillis;
|
20
|
+
/**
|
21
|
+
* 生成雪花ID
|
22
|
+
*
|
23
|
+
* @returns 返回生成的唯一ID字符串
|
24
|
+
* @throws 如果时钟回退,抛出错误
|
25
|
+
*/
|
26
|
+
generate(): string;
|
27
|
+
parse(snowflakeID: string, epoch?: number, includeVersion?: boolean): {
|
28
|
+
value: string;
|
29
|
+
timeOffset: bigint;
|
30
|
+
timestamp: number;
|
31
|
+
machineId: bigint;
|
32
|
+
sequence: bigint;
|
33
|
+
epoch: number;
|
34
|
+
version: string | undefined;
|
35
|
+
};
|
36
|
+
}
|
37
|
+
/** 将uuid转换为更简单的唯一标记id */
|
38
|
+
export declare class ShortUUID {
|
39
|
+
private alphabet;
|
40
|
+
/**
|
41
|
+
* 构造函数,用于初始化字母表
|
42
|
+
* @param {string} [alphabet] - 可选参数,用于指定自定义字母表
|
43
|
+
* 如果提供了alphabet参数,则将其设置为实例的字母表属性
|
44
|
+
* 如果未提供alphabet参数,则使用默认值
|
45
|
+
*/
|
46
|
+
constructor(alphabet?: string);
|
47
|
+
/**
|
48
|
+
* 将UUID字符串进行编码处理
|
49
|
+
* @param uuid - 需要编码的UUID字符串
|
50
|
+
* @returns 编码后的字符串
|
51
|
+
*/
|
52
|
+
encode(uuid: string, alphabet?: string): string;
|
53
|
+
/**
|
54
|
+
* 解码短UUID字符串,将其转换为UUID整数和十六进制格式
|
55
|
+
* @param shortUUID - 需要解码的短UUID字符串
|
56
|
+
* @returns 返回包含UUID整数和十六进制格式的对象
|
57
|
+
*/
|
58
|
+
decode(shortUUID: string, alphabet?: string): {
|
59
|
+
uuidInt: bigint;
|
60
|
+
uuid: string;
|
61
|
+
};
|
62
|
+
private _stringToInt;
|
63
|
+
private _intToString;
|
64
|
+
private _uuidHexToInt;
|
65
|
+
private _uuidIntToHex;
|
66
|
+
}
|
package/lib/id.js
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
/** 雪花ID, 推荐在全局构造一个对象用于生成id */
|
2
|
+
export class SnowflakeID {
|
3
|
+
/**
|
4
|
+
* 构造函数
|
5
|
+
*
|
6
|
+
* @param machineId 机器标识,默认为1
|
7
|
+
* @param epoch 时间戳起始值,默认为1288834974657
|
8
|
+
*/
|
9
|
+
constructor(machineId = 1, epoch = 1288834974657) {
|
10
|
+
/** 版本号, 默认为: 0 */
|
11
|
+
this.version = 0;
|
12
|
+
this.machineId = BigInt(machineId);
|
13
|
+
this.epoch = BigInt(epoch);
|
14
|
+
this._lastTimestamp = BigInt(0);
|
15
|
+
this._sequence = BigInt(0);
|
16
|
+
}
|
17
|
+
_getTimestamp() {
|
18
|
+
return BigInt(Date.now());
|
19
|
+
}
|
20
|
+
_waitNextMillis(cTimestamp) {
|
21
|
+
let timestamp = cTimestamp;
|
22
|
+
while (timestamp <= this._lastTimestamp) {
|
23
|
+
timestamp = BigInt(Date.now());
|
24
|
+
}
|
25
|
+
return timestamp;
|
26
|
+
}
|
27
|
+
/**
|
28
|
+
* 生成雪花ID
|
29
|
+
*
|
30
|
+
* @returns 返回生成的唯一ID字符串
|
31
|
+
* @throws 如果时钟回退,抛出错误
|
32
|
+
*/
|
33
|
+
generate() {
|
34
|
+
let cTimestamp = this._getTimestamp();
|
35
|
+
if (cTimestamp < this._lastTimestamp) {
|
36
|
+
throw new Error("Clock moved backwards");
|
37
|
+
}
|
38
|
+
if (cTimestamp === this._lastTimestamp) {
|
39
|
+
// TODO: increment sequence
|
40
|
+
// 雪花id,末尾: 12位序列号(二进制12个1等于16进制4095),最多4096个(从0到4095)
|
41
|
+
this._sequence = (this._sequence + 1n) & BigInt("0xFFF");
|
42
|
+
if (this._sequence === 0n) {
|
43
|
+
// 同一时间戳,序列号溢出,等待下一毫秒
|
44
|
+
cTimestamp = this._waitNextMillis(cTimestamp);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
else {
|
48
|
+
this._sequence = BigInt(0);
|
49
|
+
}
|
50
|
+
this._lastTimestamp = cTimestamp;
|
51
|
+
const timeDiff = cTimestamp - this.epoch;
|
52
|
+
let id = (timeDiff << BigInt(22)) |
|
53
|
+
(this.machineId << BigInt(12)) |
|
54
|
+
this._sequence;
|
55
|
+
let idstr = id.toString().padStart(19, "0");
|
56
|
+
return `${this.version}${idstr}`;
|
57
|
+
}
|
58
|
+
parse(snowflakeID, epoch, includeVersion = true) {
|
59
|
+
let version = undefined;
|
60
|
+
if (includeVersion) {
|
61
|
+
snowflakeID = snowflakeID.substring(1);
|
62
|
+
version = snowflakeID.substring(0, 1);
|
63
|
+
}
|
64
|
+
let epochTime = epoch || Number(this.epoch);
|
65
|
+
const id = BigInt(snowflakeID);
|
66
|
+
// 1FFFFFFFFFF 就是二进制的41个1, 雪花id前面41为为时间戳,间隔部分
|
67
|
+
let timeDiff = (id >> BigInt(22)) & BigInt("0x1FFFFFFFFFF");
|
68
|
+
const flowTime = Number(timeDiff) + epochTime;
|
69
|
+
// 雪花id中间10位为机器标识, 0x3FF(二进制10个1) 进行位运算
|
70
|
+
const machineId = (id >> BigInt(12)) & BigInt("0x3FF");
|
71
|
+
const sequence = id & BigInt("0xFFF");
|
72
|
+
return {
|
73
|
+
value: snowflakeID,
|
74
|
+
timeOffset: timeDiff,
|
75
|
+
timestamp: flowTime,
|
76
|
+
machineId: machineId,
|
77
|
+
sequence: sequence,
|
78
|
+
epoch: epochTime,
|
79
|
+
version,
|
80
|
+
};
|
81
|
+
}
|
82
|
+
}
|
83
|
+
/** 将uuid转换为更简单的唯一标记id */
|
84
|
+
export class ShortUUID {
|
85
|
+
/**
|
86
|
+
* 构造函数,用于初始化字母表
|
87
|
+
* @param {string} [alphabet] - 可选参数,用于指定自定义字母表
|
88
|
+
* 如果提供了alphabet参数,则将其设置为实例的字母表属性
|
89
|
+
* 如果未提供alphabet参数,则使用默认值
|
90
|
+
*/
|
91
|
+
constructor(alphabet) {
|
92
|
+
this.alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
93
|
+
if (alphabet) {
|
94
|
+
this.alphabet = alphabet;
|
95
|
+
}
|
96
|
+
}
|
97
|
+
/**
|
98
|
+
* 将UUID字符串进行编码处理
|
99
|
+
* @param uuid - 需要编码的UUID字符串
|
100
|
+
* @returns 编码后的字符串
|
101
|
+
*/
|
102
|
+
encode(uuid, alphabet) {
|
103
|
+
// 将UUID字符串转换为整数
|
104
|
+
const uuidInt = this._uuidHexToInt(uuid);
|
105
|
+
// 将整数转换为特定格式的字符串
|
106
|
+
return this._intToString(uuidInt, alphabet);
|
107
|
+
}
|
108
|
+
/**
|
109
|
+
* 解码短UUID字符串,将其转换为UUID整数和十六进制格式
|
110
|
+
* @param shortUUID - 需要解码的短UUID字符串
|
111
|
+
* @returns 返回包含UUID整数和十六进制格式的对象
|
112
|
+
*/
|
113
|
+
decode(shortUUID, alphabet) {
|
114
|
+
const uuidInt = this._stringToInt(shortUUID, alphabet);
|
115
|
+
return {
|
116
|
+
uuidInt: uuidInt,
|
117
|
+
uuid: this._uuidIntToHex(uuidInt),
|
118
|
+
};
|
119
|
+
}
|
120
|
+
_stringToInt(str, alphabet) {
|
121
|
+
if (!alphabet)
|
122
|
+
alphabet = this.alphabet;
|
123
|
+
const alphabetlen = BigInt(alphabet.length);
|
124
|
+
let result = BigInt(0);
|
125
|
+
let multiplier = BigInt(1);
|
126
|
+
const strlen = str.length;
|
127
|
+
for (let i = strlen - 1; i >= 0; i--) {
|
128
|
+
const char = str[i];
|
129
|
+
const index = alphabet.indexOf(char);
|
130
|
+
if (index === -1) {
|
131
|
+
throw new Error(`Character "${char}" not found in alphabet`);
|
132
|
+
}
|
133
|
+
result += BigInt(index) * multiplier;
|
134
|
+
multiplier *= alphabetlen;
|
135
|
+
}
|
136
|
+
return result;
|
137
|
+
}
|
138
|
+
_intToString(uuidInt, alphabet) {
|
139
|
+
if (!alphabet)
|
140
|
+
alphabet = this.alphabet;
|
141
|
+
const alphabetlen = BigInt(alphabet.length);
|
142
|
+
let num = uuidInt;
|
143
|
+
const result = [];
|
144
|
+
// uuidInt = d₀ × 1(base的0次方) + d₁ × base + d₂ × base²...
|
145
|
+
while (num) {
|
146
|
+
const index = Number(num % alphabetlen);
|
147
|
+
num = num / alphabetlen;
|
148
|
+
result.push(alphabet.charAt(index));
|
149
|
+
}
|
150
|
+
// 倒序,保证高位在前
|
151
|
+
return result.reverse().join("");
|
152
|
+
}
|
153
|
+
_uuidHexToInt(uuid) {
|
154
|
+
const uuidHex = uuid.replaceAll("-", "");
|
155
|
+
return BigInt(`0x${uuidHex}`);
|
156
|
+
}
|
157
|
+
_uuidIntToHex(uuidInt) {
|
158
|
+
const uuidHexStr = uuidInt.toString(16);
|
159
|
+
if (!/^[0-9a-fA-F]{32}$/.test(uuidHexStr)) {
|
160
|
+
throw new Error("Invalid UUID string (must be 32 hex characters)");
|
161
|
+
}
|
162
|
+
return [
|
163
|
+
uuidHexStr.slice(0, 8),
|
164
|
+
uuidHexStr.slice(8, 12),
|
165
|
+
uuidHexStr.slice(12, 16),
|
166
|
+
uuidHexStr.slice(16, 20),
|
167
|
+
uuidHexStr.slice(20),
|
168
|
+
].join("-");
|
169
|
+
}
|
170
|
+
}
|
package/lib/validator.js
CHANGED
@@ -13,7 +13,7 @@ const ruleRegexs = {
|
|
13
13
|
/** 验证跟其余数据相等的正则,一般用于验证再次输入密码 */
|
14
14
|
same: /^same:(.+)$/i,
|
15
15
|
/** 验证手机号的正则表达式 */
|
16
|
-
mobile: /^1[
|
16
|
+
mobile: /^1[3456789]\d{9}$/,
|
17
17
|
/** 非空验证的正则表达式 */
|
18
18
|
required: /^\S{1}.*/,
|
19
19
|
};
|
@@ -128,6 +128,8 @@ class Validator {
|
|
128
128
|
_validateRule(rules, value, data) {
|
129
129
|
let errMsg = "";
|
130
130
|
for (let rule of rules) {
|
131
|
+
if (!rule)
|
132
|
+
continue;
|
131
133
|
// 如果数据为空,则判断是否是必填
|
132
134
|
if (rule.rule === "required") {
|
133
135
|
if (value == null || !ruleFns.pattern(ruleRegexs.required, value)) {
|
@@ -147,7 +149,7 @@ class Validator {
|
|
147
149
|
}
|
148
150
|
}
|
149
151
|
else {
|
150
|
-
if (!ruleFns.pattern(rule.rule, value)) {
|
152
|
+
if (rule && !ruleFns.pattern(rule.rule, value)) {
|
151
153
|
errMsg = rule.message;
|
152
154
|
}
|
153
155
|
}
|
@@ -166,7 +168,7 @@ class Validator {
|
|
166
168
|
}
|
167
169
|
if (rule != null) {
|
168
170
|
if (typeof rule === "string") {
|
169
|
-
rules
|
171
|
+
rules.push(...this._parseStringRule(rule, schema.message));
|
170
172
|
}
|
171
173
|
else if (rule instanceof Array) {
|
172
174
|
for (let ruleItem of rule) {
|
@@ -181,13 +183,14 @@ class Validator {
|
|
181
183
|
});
|
182
184
|
}
|
183
185
|
else {
|
186
|
+
const emessage = ruleItem.message || schema.message || defaultMsg;
|
184
187
|
if (typeof ruleItem.rule === "string") {
|
185
|
-
rules.push(...this._parseStringRule(ruleItem.rule,
|
188
|
+
rules.push(...this._parseStringRule(ruleItem.rule, emessage));
|
186
189
|
}
|
187
190
|
else {
|
188
191
|
rules.push({
|
189
192
|
rule: ruleItem.rule,
|
190
|
-
message:
|
193
|
+
message: emessage,
|
191
194
|
});
|
192
195
|
}
|
193
196
|
}
|
@@ -225,7 +228,9 @@ class Validator {
|
|
225
228
|
rrule = ruleRegexs[r];
|
226
229
|
message = message || defaultMsgs[r];
|
227
230
|
}
|
228
|
-
|
231
|
+
if (rrule) {
|
232
|
+
rules.push({ rule: rrule, message: message, sameKey });
|
233
|
+
}
|
229
234
|
}
|
230
235
|
return rules;
|
231
236
|
}
|