@mudbean/utils 2.0.5

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.
Files changed (58) hide show
  1. package/CHANGELOG.md +170 -0
  2. package/LICENSE +15 -0
  3. package/README.md +51 -0
  4. package/cjs/array/difference.js +48 -0
  5. package/cjs/array/index.js +133 -0
  6. package/cjs/array/intersection.js +40 -0
  7. package/cjs/array/symmetricDifference.js +45 -0
  8. package/cjs/array/union.js +62 -0
  9. package/cjs/className.js +55 -0
  10. package/cjs/createBezier.js +135 -0
  11. package/cjs/getRandomNumber.js +70 -0
  12. package/cjs/getRandomString.js +143 -0
  13. package/cjs/index.js +40 -0
  14. package/cjs/isNode.js +23 -0
  15. package/cjs/object/createConstructor.js +59 -0
  16. package/cjs/performance.js +138 -0
  17. package/cjs/regexp/autoEscapedRegExp.js +44 -0
  18. package/cjs/regexp/escapeRegExp.js +22 -0
  19. package/cjs/regexp/parse.js +31 -0
  20. package/cjs/sleep.js +37 -0
  21. package/es/array/difference.d.ts +29 -0
  22. package/es/array/difference.js +46 -0
  23. package/es/array/index.d.ts +125 -0
  24. package/es/array/index.js +127 -0
  25. package/es/array/intersection.d.ts +17 -0
  26. package/es/array/intersection.js +38 -0
  27. package/es/array/symmetricDifference.d.ts +27 -0
  28. package/es/array/symmetricDifference.js +43 -0
  29. package/es/array/union.d.ts +39 -0
  30. package/es/array/union.js +60 -0
  31. package/es/className.d.ts +26 -0
  32. package/es/className.js +52 -0
  33. package/es/createBezier.d.ts +64 -0
  34. package/es/createBezier.js +133 -0
  35. package/es/getRandomNumber.d.ts +24 -0
  36. package/es/getRandomNumber.js +67 -0
  37. package/es/getRandomString.d.ts +73 -0
  38. package/es/getRandomString.js +141 -0
  39. package/es/index.d.ts +12 -0
  40. package/es/index.js +15 -0
  41. package/es/isNode.d.ts +8 -0
  42. package/es/isNode.js +20 -0
  43. package/es/object/createConstructor.d.ts +47 -0
  44. package/es/object/createConstructor.js +56 -0
  45. package/es/object/index.d.ts +2 -0
  46. package/es/performance.d.ts +61 -0
  47. package/es/performance.js +135 -0
  48. package/es/regexp/autoEscapedRegExp.d.ts +28 -0
  49. package/es/regexp/autoEscapedRegExp.js +42 -0
  50. package/es/regexp/escapeRegExp.d.ts +16 -0
  51. package/es/regexp/escapeRegExp.js +20 -0
  52. package/es/regexp/index.d.ts +2 -0
  53. package/es/regexp/parse.d.ts +6 -0
  54. package/es/regexp/parse.js +29 -0
  55. package/es/regexp/types.d.ts +10 -0
  56. package/es/sleep.d.ts +25 -0
  57. package/es/sleep.js +35 -0
  58. package/package.json +118 -0
@@ -0,0 +1,52 @@
1
+ /**
2
+ * 驼峰命名与连字符命名法的互换
3
+ */
4
+ /**
5
+ * # 连字符连接转化为小/大驼峰命名法
6
+ *
7
+ * @param str 待转化文本
8
+ * @param dividingType 连字符,缺省值为 "-"
9
+ * @param initial 是否转换第一个字符。默认值为 false (小驼峰类型)
10
+ * @returns 驼峰命名法字符串(e.g. “helloWorld”)
11
+ */
12
+ function toLowerCamelCase(
13
+ /** 待转化文本 */
14
+ str,
15
+ /** 连字符,缺省值为 "-" */
16
+ dividingType = '-',
17
+ /** 是否转换第一个字符。默认值为 false (小驼峰类型) */
18
+ initial = false) {
19
+ let result = str;
20
+ /**
21
+ * 匹配规则
22
+ *
23
+ * - 匹配到分隔符,将分隔符后面的字符转化为大写
24
+ */
25
+ const template = /[\\]|[\^]|[?]|[-]|[.]|[(]|[)]|[|]|[[]\[\]]|[{]|[}]|[+]|[*]|[$]/;
26
+ /**
27
+ * 转化首字符
28
+ * @param _str
29
+ * @param _dividingType
30
+ */
31
+ const toTransform = (_str, _dividingType) => _str.replace(new RegExp(`${template.test(_dividingType) ? `\\${_dividingType}` : _dividingType}([a-zA-Z])`, 'g'), (match, p1) => p1.toUpperCase());
32
+ // 多分隔符转化
33
+ dividingType
34
+ .split('')
35
+ .forEach((item) => (result = toTransform(result, item)));
36
+ return initial
37
+ ? result.replace(/^./, (match) => match.toUpperCase())
38
+ : result;
39
+ }
40
+ /**
41
+ * # 驼峰命名法转化为连字符连接
42
+ *
43
+ * @param str 待转化文本
44
+ * @param dividingType 分割符
45
+ * @returns 分割符转化的文本 (e.g. 'hello-world')
46
+ */
47
+ function toSplitCase(str, dividingType = '-') {
48
+ const result = str.replace(/[A-Z]/g, (match) => dividingType.concat(match.toLowerCase()));
49
+ return result.startsWith(dividingType) ? result.substring(1) : result;
50
+ }
51
+
52
+ export { toLowerCamelCase, toSplitCase };
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @file createBezier.ts
3
+ * @description 生成贝尔赛曲线
4
+ * @author Mr.MudBean <Mr.MudBean@outlook.com>
5
+ * @copyright 2026 ©️ Mr.MudBean
6
+ * @since 2026-03-26 11:24
7
+ * @version 2.0.2
8
+ * @lastModified 2026-06-11 19:07
9
+ *
10
+ * ## [贝尔赛曲线](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Reference/Values/easing-function#%E4%B8%89%E6%AC%A1%E8%B4%9D%E5%A1%9E%E5%B0%94%E7%BC%93%E5%8A%A8%E5%87%BD%E6%95%B0)
11
+ *
12
+ * 一种通过控制点生成光滑曲线的数学参数曲线,是平滑插值曲线。
13
+ *
14
+ * 广泛应用于计算机图像学、字体设计、动画游戏开发、工业设计和医学图像处理。
15
+ *
16
+ * 常见的贝尔赛曲线类型有二次和三次,其中三次贝尔赛曲线使用最多。曲线具有端点插值、凸包性。
17
+ *
18
+ */
19
+ /**
20
+ * # 在 JS 中模拟 CSS cubic-bezier(p1x, p1y, p2x, p2y)
21
+ *
22
+ * @param p1x - 第一个控制点 X
23
+ * @param p1y - 第一个控制点 Y
24
+ * @param p2x - 第二个控制点 X
25
+ * @param p2y - 第二个控制点 Y
26
+ * @returns 一个接收时间 t (0-1) 返回进度值 (0-1 或超出) 的函数
27
+ * @example
28
+ * ```ts
29
+ * // --- 使用示例 ---
30
+ *
31
+ * // 1. 定义一个类似 CSS 'ease-in-out' 的曲线: cubic-bezier(0.42, 0, 0.58, 1)
32
+ * const myEaseInOut = createBezier(0.42, 0, 0.58, 1);
33
+ *
34
+ * // 2. 定义一个带回弹效果的曲线: cubic-bezier(0.68, -0.55, 0.27, 1.55)
35
+ * const myElastic = createBezier(0.68, -0.55, 0.27, 1.55);
36
+ *
37
+ * // 3. 在 JS 动画循环中使用
38
+ * let startTime = null;
39
+ * const duration = 1000; // 1秒
40
+ * const element = document.getElementById('box');
41
+ *
42
+ * function animate(timestamp) {
43
+ * if (!startTime) startTime = timestamp;
44
+ * const elapsed = timestamp - startTime;
45
+ *
46
+ * // 计算归一化时间 (0 到 1)
47
+ * let rawTime = Math.min(elapsed / duration, 1);
48
+ *
49
+ * // 【关键点】将线性时间 rawTime 传入贝塞尔函数,得到非线性进度
50
+ * const progress = myElastic(rawTime);
51
+ *
52
+ * // 应用进度 (例如移动距离)
53
+ * const distance = 300 * progress;
54
+ * element.style.transform = `translateX(${distance}px)`;
55
+ *
56
+ * if (elapsed < duration) {
57
+ * requestAnimationFrame(animate);
58
+ * }
59
+ * }
60
+ *
61
+ * requestAnimationFrame(animate);
62
+ * ```
63
+ */
64
+ export declare function createBezier(p1x: number, p1y: number, p2x: number, p2y: number): (t: number) => number;
@@ -0,0 +1,133 @@
1
+ /**
2
+ * @file createBezier.ts
3
+ * @description 生成贝尔赛曲线
4
+ * @author Mr.MudBean <Mr.MudBean@outlook.com>
5
+ * @copyright 2026 ©️ Mr.MudBean
6
+ * @since 2026-03-26 11:24
7
+ * @version 2.0.2
8
+ * @lastModified 2026-06-11 19:07
9
+ *
10
+ * ## [贝尔赛曲线](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Reference/Values/easing-function#%E4%B8%89%E6%AC%A1%E8%B4%9D%E5%A1%9E%E5%B0%94%E7%BC%93%E5%8A%A8%E5%87%BD%E6%95%B0)
11
+ *
12
+ * 一种通过控制点生成光滑曲线的数学参数曲线,是平滑插值曲线。
13
+ *
14
+ * 广泛应用于计算机图像学、字体设计、动画游戏开发、工业设计和医学图像处理。
15
+ *
16
+ * 常见的贝尔赛曲线类型有二次和三次,其中三次贝尔赛曲线使用最多。曲线具有端点插值、凸包性。
17
+ *
18
+ */
19
+ /**
20
+ * # 在 JS 中模拟 CSS cubic-bezier(p1x, p1y, p2x, p2y)
21
+ *
22
+ * @param p1x - 第一个控制点 X
23
+ * @param p1y - 第一个控制点 Y
24
+ * @param p2x - 第二个控制点 X
25
+ * @param p2y - 第二个控制点 Y
26
+ * @returns 一个接收时间 t (0-1) 返回进度值 (0-1 或超出) 的函数
27
+ * @example
28
+ * ```ts
29
+ * // --- 使用示例 ---
30
+ *
31
+ * // 1. 定义一个类似 CSS 'ease-in-out' 的曲线: cubic-bezier(0.42, 0, 0.58, 1)
32
+ * const myEaseInOut = createBezier(0.42, 0, 0.58, 1);
33
+ *
34
+ * // 2. 定义一个带回弹效果的曲线: cubic-bezier(0.68, -0.55, 0.27, 1.55)
35
+ * const myElastic = createBezier(0.68, -0.55, 0.27, 1.55);
36
+ *
37
+ * // 3. 在 JS 动画循环中使用
38
+ * let startTime = null;
39
+ * const duration = 1000; // 1秒
40
+ * const element = document.getElementById('box');
41
+ *
42
+ * function animate(timestamp) {
43
+ * if (!startTime) startTime = timestamp;
44
+ * const elapsed = timestamp - startTime;
45
+ *
46
+ * // 计算归一化时间 (0 到 1)
47
+ * let rawTime = Math.min(elapsed / duration, 1);
48
+ *
49
+ * // 【关键点】将线性时间 rawTime 传入贝塞尔函数,得到非线性进度
50
+ * const progress = myElastic(rawTime);
51
+ *
52
+ * // 应用进度 (例如移动距离)
53
+ * const distance = 300 * progress;
54
+ * element.style.transform = `translateX(${distance}px)`;
55
+ *
56
+ * if (elapsed < duration) {
57
+ * requestAnimationFrame(animate);
58
+ * }
59
+ * }
60
+ *
61
+ * requestAnimationFrame(animate);
62
+ * ```
63
+ */
64
+ function createBezier(p1x, p1y, p2x, p2y) {
65
+ // 三次贝塞尔曲线公式: B(t) = (1-t)^3 * P0 + 3(1-t)^2*t * P1 + 3(1-t)*t^2 * P2 + t^3 * P3
66
+ // 这里 P0=(0,0), P3=(1,1)
67
+ const cx = 3 * p1x;
68
+ const bx = 3 * (p2x - p1x) - cx;
69
+ const ax = 1 - cx - bx;
70
+ const cy = 3 * p1y;
71
+ const by = 3 * (p2y - p1y) - cy;
72
+ const ay = 1 - cy - by;
73
+ // 计算给定 t 的 x 值
74
+ /**
75
+ * @param t
76
+ */
77
+ function sampleCurveX(t) {
78
+ return ((ax * t + bx) * t + cx) * t;
79
+ }
80
+ /**
81
+ * ### 计算给定 t 的 y 值
82
+ * @param t 时间进度
83
+ */
84
+ function sampleCurveY(t) {
85
+ return ((ay * t + by) * t + cy) * t;
86
+ }
87
+ /**
88
+ * ### 核心难点:已知 x (时间),求 t。因为 x(t) 是单调的,可以用牛顿迭代法求解
89
+ * @param x 时间进度
90
+ */
91
+ function getTForX(x) {
92
+ let t0, t1, t2, x2, d2;
93
+ // 初始猜测
94
+ t2 = x;
95
+ // 牛顿迭代法 (通常 8 次足够精确)
96
+ for (let i = 0; i < 8; i++) {
97
+ x2 = sampleCurveX(t2) - x;
98
+ if (Math.abs(x2) < 1e-6)
99
+ return t2;
100
+ d2 = (3 * ax * t2 + 2 * bx) * t2 + cx;
101
+ if (Math.abs(d2) < 1e-6)
102
+ break;
103
+ t2 = t2 - x2 / d2;
104
+ }
105
+ // 如果牛顿法失败,退化为二分法
106
+ t0 = 0;
107
+ t1 = 1;
108
+ t2 = x;
109
+ while (t0 < t1) {
110
+ x2 = sampleCurveX(t2);
111
+ if (Math.abs(x2 - x) < 1e-6)
112
+ return t2;
113
+ if (x > x2)
114
+ t0 = t2;
115
+ else
116
+ t1 = t2;
117
+ t2 = (t1 - t0) * 0.5 + t0;
118
+ }
119
+ return t2;
120
+ }
121
+ // 返回最终的计算函数
122
+ return function (t) {
123
+ // 边界处理:CSS 允许 t < 0 或 t > 1 (产生回弹效果)
124
+ if (t <= 0)
125
+ return sampleCurveY(0);
126
+ if (t >= 1)
127
+ return sampleCurveY(1);
128
+ const realT = getTForX(t);
129
+ return sampleCurveY(realT);
130
+ };
131
+ }
132
+
133
+ export { createBezier };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * # 获取一个随机的整数类型
3
+ *
4
+ * 您可以传入两个参数并获取它们之间的任意数字,返回值<span style="color:#ff0;">*会包含端值*</span>
5
+ *
6
+ * 如果只传递一个参数,则如果提供的值为负数,则得到一个小于(或大于)该数字的整数
7
+ *
8
+ * @param max 较大值 ,不允许为`NaN`
9
+ * @param min 较小值,不允许为 `NaN`
10
+ * @returns 任意的整数
11
+ */
12
+ export declare function getRandomInt(max?: number, min?: number): number;
13
+ /**
14
+ * # 获取任意的浮点数
15
+ *
16
+ * 您可以传入两个参数并获取它们之间的任意数字
17
+ *
18
+ * 如果只传入一个参数,则如果提供的值为负数,则获取小于(或大于)该数字的浮点数
19
+ *
20
+ * @param max 较大数,缺省值为 1
21
+ * @param min 较小值,缺省值为 0
22
+ * @returns 任意的浮点数
23
+ */
24
+ export declare function getRandomFloat(max?: number, min?: number): number;
@@ -0,0 +1,67 @@
1
+ import { isNaN, isNumber } from '@mudbean/is';
2
+
3
+ /**
4
+ * 获取随机数
5
+ */
6
+ /**
7
+ * # 获取一个随机的整数类型
8
+ *
9
+ * 您可以传入两个参数并获取它们之间的任意数字,返回值<span style="color:#ff0;">*会包含端值*</span>
10
+ *
11
+ * 如果只传递一个参数,则如果提供的值为负数,则得到一个小于(或大于)该数字的整数
12
+ *
13
+ * @param max 较大值 ,不允许为`NaN`
14
+ * @param min 较小值,不允许为 `NaN`
15
+ * @returns 任意的整数
16
+ */
17
+ function getRandomInt(max = 1, min = 0) {
18
+ // 判断是否为 NaN 或 不是数字
19
+ if (!isFinite(max) ||
20
+ !isFinite(min) ||
21
+ isNaN(max) ||
22
+ isNaN(min) ||
23
+ !isNumber(max) ||
24
+ !isNumber(min)) {
25
+ throw new TypeError('getRandomInt: max or min is NaN or is not a number');
26
+ }
27
+ /** 获取最小值 */
28
+ let _min = Math.ceil(Number(min)),
29
+ /** 获取最大值 */
30
+ _max = Math.floor(Number(max));
31
+ // 两值相等时,直接返回最大值
32
+ if (_max === _min)
33
+ return _max;
34
+ // 两值交换
35
+ if (_min > _max)
36
+ [_max, _min] = [_min, _max];
37
+ return Math.round(Math.random() * (_max - _min) + _min);
38
+ }
39
+ /**
40
+ * # 获取任意的浮点数
41
+ *
42
+ * 您可以传入两个参数并获取它们之间的任意数字
43
+ *
44
+ * 如果只传入一个参数,则如果提供的值为负数,则获取小于(或大于)该数字的浮点数
45
+ *
46
+ * @param max 较大数,缺省值为 1
47
+ * @param min 较小值,缺省值为 0
48
+ * @returns 任意的浮点数
49
+ */
50
+ function getRandomFloat(max = 1, min = 0) {
51
+ // 判断是否为 NaN 或 不是数字
52
+ if (!isFinite(max) ||
53
+ !isFinite(min) ||
54
+ isNaN(max) ||
55
+ isNaN(min) ||
56
+ !isNumber(max) ||
57
+ !isNumber(min)) {
58
+ throw new TypeError('getRandomInt: max or min is NaN or is not a number');
59
+ }
60
+ if (max == min)
61
+ max++;
62
+ if (min > max)
63
+ [max, min] = [min, max];
64
+ return Math.random() * (max - min) + min;
65
+ }
66
+
67
+ export { getRandomFloat, getRandomInt };
@@ -0,0 +1,73 @@
1
+ /**
2
+ * # 随机字符串生成器
3
+ */
4
+ export type RandomStringOptions = {
5
+ /**
6
+ * 字符串长度
7
+ *
8
+ * @default 32
9
+ */
10
+ length?: number;
11
+ /**
12
+ * 字符集
13
+ * @default '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
14
+ */
15
+ chars?: string;
16
+ /**
17
+ * 是否包含数字
18
+ *
19
+ * @default false
20
+ */
21
+ includeNumbers?: boolean;
22
+ /**
23
+ * 是否包含大写字母
24
+ *
25
+ * @default false
26
+ */
27
+ includeUppercaseLetters?: boolean;
28
+ /**
29
+ * 是否包含特殊字符
30
+ *
31
+ * @default false
32
+ */
33
+ includeSpecial?: boolean;
34
+ /**
35
+ * 字符类型
36
+ *
37
+ * 缺省值为 'string',可选为 'uuid'
38
+ *
39
+ * @default 'string''
40
+ */
41
+ type?: 'string' | 'uuid';
42
+ };
43
+ /**
44
+ * # 获取简单的随机字符串
45
+ *
46
+ * ```ts
47
+ * type RandomStringOptions = {
48
+ * length?: number; // 字符串长度
49
+ * chars?: string; // 包含英文字符
50
+ * includeNumbers?: boolean; // 包含数字
51
+ * includeUppercaseLetters?: boolean; // 包含大写字符
52
+ * includeSpecial?: boolean; // 包含特殊字符
53
+ * type?: 'string' | 'uuid'; // 生成类型
54
+ * }
55
+ * ```
56
+ *
57
+ * @param options - 字符串生成参数
58
+ * @returns - 随机字符串
59
+ * @example
60
+ * ```ts
61
+ * import { getRandomString } from '@mudbean/utils';
62
+ *
63
+ * // 获取简单的随机字符串
64
+ * // 'abcdefg'
65
+ * getRandomString(7);
66
+ *
67
+ * // 获取随机的字符串
68
+ * getRandomString({
69
+ * length: 7,
70
+ * })
71
+ * ```
72
+ */
73
+ export declare function getRandomString(options?: RandomStringOptions | number): string;
@@ -0,0 +1,141 @@
1
+ import { isPlainObject, isNumber, isNaN, isUndefined } from '@mudbean/is';
2
+ import { ObjectAssign } from './object/createConstructor.js';
3
+ import { getRandomInt } from './getRandomNumber.js';
4
+
5
+ /**
6
+ * 获取随机字符串
7
+ */
8
+ /**
9
+ * # 获取简单的随机字符串
10
+ *
11
+ * ```ts
12
+ * type RandomStringOptions = {
13
+ * length?: number; // 字符串长度
14
+ * chars?: string; // 包含英文字符
15
+ * includeNumbers?: boolean; // 包含数字
16
+ * includeUppercaseLetters?: boolean; // 包含大写字符
17
+ * includeSpecial?: boolean; // 包含特殊字符
18
+ * type?: 'string' | 'uuid'; // 生成类型
19
+ * }
20
+ * ```
21
+ *
22
+ * @param options - 字符串生成参数
23
+ * @returns - 随机字符串
24
+ * @example
25
+ * ```ts
26
+ * import { getRandomString } from '@mudbean/utils';
27
+ *
28
+ * // 获取简单的随机字符串
29
+ * // 'abcdefg'
30
+ * getRandomString(7);
31
+ *
32
+ * // 获取随机的字符串
33
+ * getRandomString({
34
+ * length: 7,
35
+ * })
36
+ * ```
37
+ */
38
+ function getRandomString(options) {
39
+ // 验证输入参数
40
+ if (
41
+ // 参数类型错误
42
+ (!isPlainObject(options) && !isNumber(options)) ||
43
+ // 参数为 NaN
44
+ (isNumber(options) && isNaN(options)) ||
45
+ // 参数为数字时为无穷大
46
+ (isNumber(options) && !isFinite(options)) ||
47
+ // 参数为数字时为非整数
48
+ (isNumber(options) && !Number.isInteger(options)) ||
49
+ // 参数为数字时为负数
50
+ (isNumber(options) && Number.isInteger(options) && options < 1) ||
51
+ // 参数为数值然而却小于 1
52
+ (isNumber(options) && options < 1) ||
53
+ // 参数为对象但是 length 属性非数值
54
+ (isPlainObject(options) &&
55
+ (!isNumber(options.length) ||
56
+ options.length < 1 ||
57
+ !Number.isInteger(options.length))))
58
+ throw new TypeError('参数类型错误 ❌ (getRandomString)');
59
+ const initOptions = {
60
+ length: 32,
61
+ chars: 'abcdefghijklmnopqrstuvwxyz',
62
+ chars2: '0123456789',
63
+ chars3: '!@#$%^&*()_+~`|}{[]:;?><,./-=',
64
+ type: 'string',
65
+ includeUppercaseLetters: false,
66
+ includeNumbers: false,
67
+ includeSpecial: false,
68
+ };
69
+ /// 生成 UUID
70
+ if (initOptions.type === 'uuid')
71
+ return crypto.randomUUID();
72
+ // 验证输入参数
73
+ if (isNumber(options) && Number.isInteger(options) && options > 0)
74
+ ObjectAssign(initOptions, { length: options });
75
+ if (isPlainObject(options)) {
76
+ ObjectAssign(initOptions, options);
77
+ initOptions.length = initOptions.length < 1 ? 32 : initOptions.length;
78
+ }
79
+ /** 生成随机字符串 */
80
+ const templateCharsArr = initOptions.chars.split('');
81
+ // 添加大写字母
82
+ if (initOptions.includeUppercaseLetters)
83
+ interleaveString(templateCharsArr, initOptions.chars.toUpperCase());
84
+ // 添加数字
85
+ if (initOptions.includeNumbers)
86
+ interleaveString(templateCharsArr, initOptions.chars2);
87
+ // 添加特殊字符
88
+ if (initOptions.includeSpecial)
89
+ interleaveString(templateCharsArr, initOptions.chars3);
90
+ /** 结果字符串 */
91
+ let result = '';
92
+ /** 混淆后的字符串 */
93
+ const str = templateCharsArr.join('');
94
+ /** 混淆后字符长度 */
95
+ const strLen = str.length;
96
+ if (globalThis && globalThis.crypto && globalThis.crypto.getRandomValues) {
97
+ // 使用密码学安全的随机数生成器
98
+ const bytes = globalThis.crypto.getRandomValues(new Uint8Array(initOptions.length));
99
+ /** 获取最后的 chars 数据 */
100
+ // 循环遍历
101
+ bytes.forEach(byte => (result += str[byte % strLen]));
102
+ }
103
+ else {
104
+ for (let i = 0; i < initOptions.length; i++)
105
+ result += str[getRandomInt(strLen - 1)];
106
+ }
107
+ /**
108
+ * # 字符串交叉函数
109
+ *
110
+ * 非线形串交叉,对相交叉
111
+ *
112
+ * @param str1 - 字符串1
113
+ * @param str2 - 字符串2
114
+ * @returns - 交叉后的字符串
115
+ * @example
116
+ *
117
+ * ```ts
118
+ * interleaveString('abc', '123') // 'a1b2c3'
119
+ * ```
120
+ */
121
+ function interleaveString(str1, str2) {
122
+ const str1Length = str1.length, str2Length = str2.length;
123
+ const maxLength = Math.max(str1Length, str2Length);
124
+ for (let i = 0; i < maxLength; i++) {
125
+ if (i < str1Length && !isUndefined(str2[i])) {
126
+ str1[i] += str2[i];
127
+ }
128
+ else if (i < str2Length) {
129
+ str1[i] = str2[i];
130
+ }
131
+ }
132
+ }
133
+ /// 结果字符串不包含字符
134
+ if (!/[a-zA-Z]/.test(result))
135
+ return String.fromCharCode(getRandomInt(97, 122)).concat(result.slice(1));
136
+ while (!/^[a-zA-Z]$/.test(result[0]))
137
+ result = result.slice(1) + result[0];
138
+ return result;
139
+ }
140
+
141
+ export { getRandomString };
package/es/index.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ export { toLowerCamelCase, toSplitCase } from './className';
2
+ export type { CreateConstructor } from './object/createConstructor';
3
+ export { createConstructor, ObjectAssign } from './object/createConstructor';
4
+ export { getRandomFloat, getRandomInt } from './getRandomNumber';
5
+ export { getRandomString } from './getRandomString';
6
+ export { throttle, debounce } from './performance';
7
+ export type { DebounceAndThrottleReturnType, debounce_throttle_options, } from './performance';
8
+ export { escapeRegExp, autoEscapedRegExp } from './regexp';
9
+ export { isBrowser, isNode } from './isNode';
10
+ export { intersection, enArr, union, difference, symmetricDifference, } from './array';
11
+ export { sleep } from './sleep';
12
+ export { createBezier } from './createBezier';
package/es/index.js ADDED
@@ -0,0 +1,15 @@
1
+ export { toLowerCamelCase, toSplitCase } from './className.js';
2
+ export { ObjectAssign, createConstructor } from './object/createConstructor.js';
3
+ export { getRandomFloat, getRandomInt } from './getRandomNumber.js';
4
+ export { getRandomString } from './getRandomString.js';
5
+ export { debounce, throttle } from './performance.js';
6
+ export { escapeRegExp } from './regexp/escapeRegExp.js';
7
+ export { autoEscapedRegExp } from './regexp/autoEscapedRegExp.js';
8
+ export { isBrowser, isNode } from './isNode.js';
9
+ export { enArr } from './array/index.js';
10
+ export { sleep } from './sleep.js';
11
+ export { createBezier } from './createBezier.js';
12
+ export { difference } from './array/difference.js';
13
+ export { intersection } from './array/intersection.js';
14
+ export { symmetricDifference } from './array/symmetricDifference.js';
15
+ export { union } from './array/union.js';
package/es/isNode.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * # 判断当前环境是否为 node 环境
3
+ */
4
+ export declare function isNode(): boolean;
5
+ /**
6
+ * # 是否为浏览器环境
7
+ */
8
+ export declare function isBrowser(): boolean;
package/es/isNode.js ADDED
@@ -0,0 +1,20 @@
1
+ import { isUndefined } from '@mudbean/is';
2
+
3
+ /**
4
+ * # 判断当前环境是否为 node 环境
5
+ */
6
+ function isNode() {
7
+ return !isUndefined((globalThis &&
8
+ globalThis.process &&
9
+ globalThis.process.versions &&
10
+ globalThis.process.versions.node) ||
11
+ undefined);
12
+ }
13
+ /**
14
+ * # 是否为浏览器环境
15
+ */
16
+ function isBrowser() {
17
+ return !isNode();
18
+ }
19
+
20
+ export { isBrowser, isNode };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * 构建构建的构建函数
3
+ */
4
+ export interface CreateConstructor<T, Args extends unknown[] = unknown[]> {
5
+ new (...args: Args): T;
6
+ }
7
+ /**
8
+ * # 构建一个 Constructor 构造函数
9
+ *
10
+ * 接收一个构造函数,然后返回 TS 能识别的构造函数自身
11
+ *
12
+ * 函数本身并没有执行任何逻辑,仅是简单的返回了实参自身
13
+ *
14
+ * 而经过该函数的包装,构造函数成了能够被 TS 识别为可用 new 实例的构造函数
15
+ *
16
+ * @param constructor - 传入一个构造函数
17
+ * @returns 返回传入的构造函数
18
+ * @example
19
+ * ```ts
20
+ * import { createConstructor } from "@mudbean/utils";
21
+ *
22
+ * type Tom = {
23
+ * a: number
24
+ * }
25
+ *
26
+ * function _Tom (this: TomType): Tom {
27
+ * this.a = 1;
28
+ *
29
+ * return this;
30
+ * }
31
+ *
32
+ * // 逻辑上没有错,但是会造成 ts 显示
33
+ * // 其目标缺少构造签名的 "new" 表达式隐式具有 "any" 类型。ts(7009)
34
+ * const a = new _Tom();
35
+ *
36
+ * const tomConstructor = createConstructor(_tom);
37
+ *
38
+ * const b = new tomConstructor(); // 这时就不会显示错误
39
+ * ```
40
+ */
41
+ export declare function createConstructor<T, Args extends unknown[] = unknown[]>(constructor: (...argumentList: Args) => T): CreateConstructor<T, Args>;
42
+ /**
43
+ * # 对象的 assign 用法
44
+ * @param target
45
+ * @param bar
46
+ */
47
+ export declare function ObjectAssign(target: Record<string, unknown>, bar: Record<string, unknown>): Record<string, unknown>;