sculp-js 0.0.2 → 1.0.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/LICENSE.md +1 -1
- package/README.md +22 -1
- package/lib/cjs/array.js +32 -55
- package/lib/cjs/async.js +3 -3
- package/lib/cjs/clipboard.js +3 -3
- package/lib/cjs/cookie.js +5 -5
- package/lib/cjs/date.js +142 -24
- package/lib/cjs/dom.js +24 -10
- package/lib/cjs/download.js +9 -9
- package/lib/cjs/easing.js +1 -1
- package/lib/cjs/file.js +5 -4
- package/lib/cjs/func.js +160 -0
- package/lib/cjs/index.js +28 -2
- package/lib/cjs/number.js +82 -0
- package/lib/cjs/object.js +13 -11
- package/lib/cjs/path.js +1 -1
- package/lib/cjs/qs.js +5 -5
- package/lib/cjs/random.js +72 -0
- package/lib/cjs/string.js +40 -7
- package/lib/cjs/type.js +12 -2
- package/lib/cjs/unique.js +83 -0
- package/lib/cjs/url.js +1 -1
- package/lib/cjs/watermark.js +8 -9
- package/lib/es/array.js +33 -55
- package/lib/es/async.js +3 -3
- package/lib/es/clipboard.js +3 -3
- package/lib/es/cookie.js +5 -5
- package/lib/es/date.js +139 -25
- package/lib/es/dom.js +24 -11
- package/lib/es/download.js +9 -9
- package/lib/es/easing.js +1 -1
- package/lib/es/file.js +5 -4
- package/lib/es/func.js +154 -0
- package/lib/es/index.js +10 -6
- package/lib/es/number.js +77 -0
- package/lib/es/object.js +12 -10
- package/lib/es/path.js +1 -1
- package/lib/es/qs.js +5 -5
- package/lib/es/random.js +67 -0
- package/lib/es/string.js +40 -8
- package/lib/es/type.js +12 -3
- package/lib/es/unique.js +79 -0
- package/lib/es/url.js +1 -1
- package/lib/es/watermark.js +8 -9
- package/lib/index.d.ts +254 -80
- package/lib/umd/index.js +637 -132
- package/package.json +36 -12
package/lib/cjs/file.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* 选择本地文件
|
|
11
|
-
* @param {
|
|
12
|
-
* @
|
|
11
|
+
* @param {string} accept 上传的文件类型,用于过滤
|
|
12
|
+
* @param {Function} changeCb 选择文件回调
|
|
13
|
+
* @returns {HTMLInputElement}
|
|
13
14
|
*/
|
|
14
|
-
function chooseLocalFile(
|
|
15
|
+
function chooseLocalFile(accept, changeCb) {
|
|
15
16
|
const inputObj = document.createElement('input');
|
|
16
17
|
inputObj.setAttribute('id', String(Date.now()));
|
|
17
18
|
inputObj.setAttribute('type', 'file');
|
package/lib/cjs/func.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
|
+
* (c) 2023-2023 chandq
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 防抖函数
|
|
11
|
+
* 当函数被连续调用时,该函数并不执行,只有当其全部停止调用超过一定时间后才执行1次。
|
|
12
|
+
* 例如:上电梯的时候,大家陆陆续续进来,电梯的门不会关上,只有当一段时间都没有人上来,电梯才会关门。
|
|
13
|
+
* @param {F} func
|
|
14
|
+
* @param {number} wait
|
|
15
|
+
* @returns {DebounceFunc<F>}
|
|
16
|
+
*/
|
|
17
|
+
const debounce = (func, wait) => {
|
|
18
|
+
let timeout;
|
|
19
|
+
let canceled = false;
|
|
20
|
+
const f = function (...args) {
|
|
21
|
+
if (canceled)
|
|
22
|
+
return;
|
|
23
|
+
clearTimeout(timeout);
|
|
24
|
+
timeout = setTimeout(() => {
|
|
25
|
+
func.call(this, ...args);
|
|
26
|
+
}, wait);
|
|
27
|
+
};
|
|
28
|
+
f.cancel = () => {
|
|
29
|
+
clearTimeout(timeout);
|
|
30
|
+
canceled = true;
|
|
31
|
+
};
|
|
32
|
+
return f;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* 节流函数
|
|
36
|
+
* 节流就是节约流量,将连续触发的事件稀释成预设评率。 比如每间隔1秒执行一次函数,无论这期间触发多少次事件。
|
|
37
|
+
* 这有点像公交车,无论在站点等车的人多不多,公交车只会按时来一班,不会来一个人就来一辆公交车。
|
|
38
|
+
* @param {F} func
|
|
39
|
+
* @param {number} wait
|
|
40
|
+
* @param {boolean} immediate
|
|
41
|
+
* @returns {ThrottleFunc<F>}
|
|
42
|
+
*/
|
|
43
|
+
const throttle = (func, wait, immediate) => {
|
|
44
|
+
let timeout;
|
|
45
|
+
let canceled = false;
|
|
46
|
+
let lastCalledTime = 0;
|
|
47
|
+
const f = function (...args) {
|
|
48
|
+
if (canceled)
|
|
49
|
+
return;
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
const call = () => {
|
|
52
|
+
lastCalledTime = now;
|
|
53
|
+
func.call(this, ...args);
|
|
54
|
+
};
|
|
55
|
+
// 第一次执行
|
|
56
|
+
if (lastCalledTime === 0) {
|
|
57
|
+
if (immediate) {
|
|
58
|
+
return call();
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
lastCalledTime = now;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const remain = lastCalledTime + wait - now;
|
|
66
|
+
if (remain > 0) {
|
|
67
|
+
clearTimeout(timeout);
|
|
68
|
+
timeout = setTimeout(() => call(), wait);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
call();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
f.cancel = () => {
|
|
75
|
+
clearTimeout(timeout);
|
|
76
|
+
canceled = true;
|
|
77
|
+
};
|
|
78
|
+
return f;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* 单次函数
|
|
82
|
+
* @param {AnyFunc} func
|
|
83
|
+
* @returns {AnyFunc}
|
|
84
|
+
*/
|
|
85
|
+
const once = (func) => {
|
|
86
|
+
let called = false;
|
|
87
|
+
let result;
|
|
88
|
+
return function (...args) {
|
|
89
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
90
|
+
if (called)
|
|
91
|
+
return result;
|
|
92
|
+
called = true;
|
|
93
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
94
|
+
result = func.call(this, ...args);
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
96
|
+
return result;
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* 设置全局变量
|
|
101
|
+
* @param {string | number | symbol} key
|
|
102
|
+
* @param val
|
|
103
|
+
*/
|
|
104
|
+
function setGlobal(key, val) {
|
|
105
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
106
|
+
// @ts-ignore
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
108
|
+
if (typeof globalThis !== 'undefined')
|
|
109
|
+
globalThis[key] = val;
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
111
|
+
// @ts-ignore
|
|
112
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
113
|
+
else if (typeof window !== 'undefined')
|
|
114
|
+
window[key] = val;
|
|
115
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
116
|
+
// @ts-ignore
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
118
|
+
else if (typeof global !== 'undefined')
|
|
119
|
+
global[key] = val;
|
|
120
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
121
|
+
// @ts-ignore
|
|
122
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
123
|
+
else if (typeof self !== 'undefined')
|
|
124
|
+
self[key] = val;
|
|
125
|
+
else
|
|
126
|
+
throw new SyntaxError('当前环境下无法设置全局属性');
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 设置全局变量
|
|
130
|
+
* @param {string | number | symbol} key
|
|
131
|
+
* @param val
|
|
132
|
+
*/
|
|
133
|
+
function getGlobal(key) {
|
|
134
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
135
|
+
// @ts-ignore
|
|
136
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
137
|
+
if (typeof globalThis !== 'undefined')
|
|
138
|
+
return globalThis[key];
|
|
139
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
140
|
+
// @ts-ignore
|
|
141
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
142
|
+
else if (typeof window !== 'undefined')
|
|
143
|
+
return window[key];
|
|
144
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
145
|
+
// @ts-ignore
|
|
146
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
147
|
+
else if (typeof global !== 'undefined')
|
|
148
|
+
return global[key];
|
|
149
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
150
|
+
// @ts-ignore
|
|
151
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
152
|
+
else if (typeof self !== 'undefined')
|
|
153
|
+
return self[key];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
exports.debounce = debounce;
|
|
157
|
+
exports.getGlobal = getGlobal;
|
|
158
|
+
exports.once = once;
|
|
159
|
+
exports.setGlobal = setGlobal;
|
|
160
|
+
exports.throttle = throttle;
|
package/lib/cjs/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -21,6 +21,10 @@ var url = require('./url.js');
|
|
|
21
21
|
var async = require('./async.js');
|
|
22
22
|
var file = require('./file.js');
|
|
23
23
|
var watermark = require('./watermark.js');
|
|
24
|
+
var func = require('./func.js');
|
|
25
|
+
var random = require('./random.js');
|
|
26
|
+
var number = require('./number.js');
|
|
27
|
+
var unique = require('./unique.js');
|
|
24
28
|
|
|
25
29
|
|
|
26
30
|
|
|
@@ -29,7 +33,6 @@ exports.arrayEachAsync = array.arrayEachAsync;
|
|
|
29
33
|
exports.arrayInsertBefore = array.arrayInsertBefore;
|
|
30
34
|
exports.arrayLike = array.arrayLike;
|
|
31
35
|
exports.arrayRemove = array.arrayRemove;
|
|
32
|
-
exports.asyncForEach = array.asyncForEach;
|
|
33
36
|
exports.deepTraversal = array.deepTraversal;
|
|
34
37
|
exports.getTreeIds = array.getTreeIds;
|
|
35
38
|
exports.copyText = clipboard.copyText;
|
|
@@ -38,8 +41,13 @@ exports.cookieGet = cookie.cookieGet;
|
|
|
38
41
|
exports.cookieSet = cookie.cookieSet;
|
|
39
42
|
exports.calculateDate = date.calculateDate;
|
|
40
43
|
exports.calculateDateTime = date.calculateDateTime;
|
|
44
|
+
exports.dateParse = date.dateParse;
|
|
45
|
+
exports.dateToEnd = date.dateToEnd;
|
|
46
|
+
exports.dateToStart = date.dateToStart;
|
|
41
47
|
exports.formatDate = date.formatDate;
|
|
48
|
+
exports.isValidDate = date.isValidDate;
|
|
42
49
|
exports.addClass = dom.addClass;
|
|
50
|
+
exports.getComputedCssVal = dom.getComputedCssVal;
|
|
43
51
|
exports.getStyle = dom.getStyle;
|
|
44
52
|
exports.hasClass = dom.hasClass;
|
|
45
53
|
exports.isDomReady = dom.isDomReady;
|
|
@@ -70,6 +78,7 @@ exports.qsStringify = qs.qsStringify;
|
|
|
70
78
|
exports.STRING_ARABIC_NUMERALS = string.STRING_ARABIC_NUMERALS;
|
|
71
79
|
exports.STRING_LOWERCASE_ALPHA = string.STRING_LOWERCASE_ALPHA;
|
|
72
80
|
exports.STRING_UPPERCASE_ALPHA = string.STRING_UPPERCASE_ALPHA;
|
|
81
|
+
exports.getStrWidthPx = string.getStrWidthPx;
|
|
73
82
|
exports.stringAssign = string.stringAssign;
|
|
74
83
|
exports.stringCamelCase = string.stringCamelCase;
|
|
75
84
|
exports.stringEscapeHtml = string.stringEscapeHtml;
|
|
@@ -91,6 +100,7 @@ exports.isRegExp = type.isRegExp;
|
|
|
91
100
|
exports.isString = type.isString;
|
|
92
101
|
exports.isSymbol = type.isSymbol;
|
|
93
102
|
exports.isUndefined = type.isUndefined;
|
|
103
|
+
exports.typeIs = type.typeIs;
|
|
94
104
|
exports.urlDelParams = url.urlDelParams;
|
|
95
105
|
exports.urlParse = url.urlParse;
|
|
96
106
|
exports.urlSetParams = url.urlSetParams;
|
|
@@ -99,3 +109,19 @@ exports.asyncMap = async.asyncMap;
|
|
|
99
109
|
exports.wait = async.wait;
|
|
100
110
|
exports.chooseLocalFile = file.chooseLocalFile;
|
|
101
111
|
exports.genCanvasWM = watermark.genCanvasWM;
|
|
112
|
+
exports.debounce = func.debounce;
|
|
113
|
+
exports.getGlobal = func.getGlobal;
|
|
114
|
+
exports.once = func.once;
|
|
115
|
+
exports.setGlobal = func.setGlobal;
|
|
116
|
+
exports.throttle = func.throttle;
|
|
117
|
+
exports.STRING_POOL = random.STRING_POOL;
|
|
118
|
+
exports.randomNumber = random.randomNumber;
|
|
119
|
+
exports.randomString = random.randomString;
|
|
120
|
+
exports.randomUuid = random.randomUuid;
|
|
121
|
+
exports.HEX_POOL = number.HEX_POOL;
|
|
122
|
+
exports.formatNumber = number.formatNumber;
|
|
123
|
+
exports.numberAbbr = number.numberAbbr;
|
|
124
|
+
exports.numberToHex = number.numberToHex;
|
|
125
|
+
exports.UNIQUE_NUMBER_SAFE_LENGTH = unique.UNIQUE_NUMBER_SAFE_LENGTH;
|
|
126
|
+
exports.uniqueNumber = unique.uniqueNumber;
|
|
127
|
+
exports.uniqueString = unique.uniqueString;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
|
+
* (c) 2023-2023 chandq
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
var func = require('./func.js');
|
|
10
|
+
var string = require('./string.js');
|
|
11
|
+
|
|
12
|
+
const HEX_POOL = `${string.STRING_ARABIC_NUMERALS}${string.STRING_UPPERCASE_ALPHA}${string.STRING_LOWERCASE_ALPHA}`;
|
|
13
|
+
const supportBigInt = typeof BigInt !== 'undefined';
|
|
14
|
+
const jsbi = () => func.getGlobal('JSBI');
|
|
15
|
+
const toBigInt = (n) => (supportBigInt ? BigInt(n) : jsbi().BigInt(n));
|
|
16
|
+
const divide = (x, y) => (supportBigInt ? x / y : jsbi().divide(x, y));
|
|
17
|
+
const remainder = (x, y) => (supportBigInt ? x % y : jsbi().remainder(x, y));
|
|
18
|
+
/**
|
|
19
|
+
* 将十进制转换成任意进制
|
|
20
|
+
* @param {number | string} decimal 十进制数值或字符串,可以是任意长度,会使用大数进行计算
|
|
21
|
+
* @param {string} [hexPool] 进制池,默认 62 进制
|
|
22
|
+
* @returns {string}
|
|
23
|
+
*/
|
|
24
|
+
function numberToHex(decimal, hexPool = HEX_POOL) {
|
|
25
|
+
if (hexPool.length < 2)
|
|
26
|
+
throw new Error('进制池长度不能少于 2');
|
|
27
|
+
if (!supportBigInt) {
|
|
28
|
+
throw new Error('需要安装 jsbi 模块并将 JSBI 设置为全局变量:\nimport JSBI from "jsbi"; window.JSBI = JSBI;');
|
|
29
|
+
}
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
31
|
+
let bigInt = toBigInt(decimal);
|
|
32
|
+
const ret = [];
|
|
33
|
+
const { length } = hexPool;
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
35
|
+
const bigLength = toBigInt(length);
|
|
36
|
+
const execute = () => {
|
|
37
|
+
const y = Number(remainder(bigInt, bigLength));
|
|
38
|
+
bigInt = divide(bigInt, bigLength);
|
|
39
|
+
ret.unshift(hexPool[y]);
|
|
40
|
+
if (bigInt > 0) {
|
|
41
|
+
execute();
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
execute();
|
|
45
|
+
return ret.join('');
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 缩写
|
|
49
|
+
* @param {number | string} num
|
|
50
|
+
* @param {Array<string>} units
|
|
51
|
+
* @param {number} ratio
|
|
52
|
+
* @param {number} exponent
|
|
53
|
+
* @returns {string}
|
|
54
|
+
*/
|
|
55
|
+
const numberAbbr = (num, units, ratio = 1000, exponent) => {
|
|
56
|
+
const { length } = units;
|
|
57
|
+
if (length === 0)
|
|
58
|
+
throw new Error('至少需要一个单位');
|
|
59
|
+
let num2 = Number(num);
|
|
60
|
+
let times = 0;
|
|
61
|
+
while (num2 >= ratio && times < length - 1) {
|
|
62
|
+
num2 = num2 / ratio;
|
|
63
|
+
times++;
|
|
64
|
+
}
|
|
65
|
+
const value = num2.toFixed(exponent);
|
|
66
|
+
const unit = units[times];
|
|
67
|
+
return value.toString() + '' + unit;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* 将数字格式化成千位分隔符显示的字符串
|
|
71
|
+
* @param {number} val 数字
|
|
72
|
+
* @param {'int' | 'float'} type 展示分段显示的类型 int:整型 | float:浮点型
|
|
73
|
+
* @returns {string}
|
|
74
|
+
*/
|
|
75
|
+
function formatNumber(val, type = 'int') {
|
|
76
|
+
return type === 'int' ? parseInt(String(val)).toLocaleString() : Number(val).toLocaleString('en-US');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
exports.HEX_POOL = HEX_POOL;
|
|
80
|
+
exports.formatNumber = formatNumber;
|
|
81
|
+
exports.numberAbbr = numberAbbr;
|
|
82
|
+
exports.numberToHex = numberToHex;
|
package/lib/cjs/object.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -29,20 +29,22 @@ const isPlainObject = (obj) => {
|
|
|
29
29
|
* @param {string} key
|
|
30
30
|
* @returns {boolean}
|
|
31
31
|
*/
|
|
32
|
-
|
|
32
|
+
function objectHas(obj, key) {
|
|
33
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
34
|
+
}
|
|
33
35
|
/**
|
|
34
36
|
* 遍历对象,返回 false 中断遍历
|
|
35
37
|
* @param {O} obj
|
|
36
38
|
* @param {(val: O[keyof O], key: keyof O) => (boolean | void)} iterator
|
|
37
39
|
*/
|
|
38
|
-
|
|
40
|
+
function objectEach(obj, iterator) {
|
|
39
41
|
for (const key in obj) {
|
|
40
42
|
if (!objectHas(obj, key))
|
|
41
43
|
continue;
|
|
42
44
|
if (iterator(obj[key], key) === false)
|
|
43
45
|
break;
|
|
44
46
|
}
|
|
45
|
-
}
|
|
47
|
+
}
|
|
46
48
|
/**
|
|
47
49
|
* 异步遍历对象,返回 false 中断遍历
|
|
48
50
|
* @param {O} obj
|
|
@@ -109,8 +111,8 @@ function objectOmit(obj, keys) {
|
|
|
109
111
|
const merge = (map, source, target) => {
|
|
110
112
|
if (type.isUndefined(target))
|
|
111
113
|
return source;
|
|
112
|
-
const sourceType = type.
|
|
113
|
-
const targetType = type.
|
|
114
|
+
const sourceType = type.typeIs(source);
|
|
115
|
+
const targetType = type.typeIs(target);
|
|
114
116
|
if (sourceType !== targetType) {
|
|
115
117
|
if (type.isArray(target))
|
|
116
118
|
return merge(map, [], target);
|
|
@@ -148,7 +150,7 @@ const merge = (map, source, target) => {
|
|
|
148
150
|
* @param {ObjectAssignItem | undefined} targets
|
|
149
151
|
* @returns {R}
|
|
150
152
|
*/
|
|
151
|
-
|
|
153
|
+
function objectAssign(source, ...targets) {
|
|
152
154
|
const map = new Map();
|
|
153
155
|
for (let i = 0; i < targets.length; i++) {
|
|
154
156
|
const target = targets[i];
|
|
@@ -158,7 +160,7 @@ const objectAssign = (source, ...targets) => {
|
|
|
158
160
|
}
|
|
159
161
|
map.clear();
|
|
160
162
|
return source;
|
|
161
|
-
}
|
|
163
|
+
}
|
|
162
164
|
/**
|
|
163
165
|
* 对象填充
|
|
164
166
|
* @param {Partial<R>} source
|
|
@@ -166,7 +168,7 @@ const objectAssign = (source, ...targets) => {
|
|
|
166
168
|
* @param {(s: Partial<R>, t: Partial<R>, key: keyof R) => boolean} fillable
|
|
167
169
|
* @returns {R}
|
|
168
170
|
*/
|
|
169
|
-
|
|
171
|
+
function objectFill(source, target, fillable) {
|
|
170
172
|
const _fillable = fillable || ((source, target, key) => source[key] === undefined);
|
|
171
173
|
objectEach(target, (val, key) => {
|
|
172
174
|
if (_fillable(source, target, key)) {
|
|
@@ -174,7 +176,7 @@ const objectFill = (source, target, fillable) => {
|
|
|
174
176
|
}
|
|
175
177
|
});
|
|
176
178
|
return source;
|
|
177
|
-
}
|
|
179
|
+
}
|
|
178
180
|
function objectGet(obj, path, strict = false) {
|
|
179
181
|
path = path.replace(/\[(\w+)\]/g, '.$1');
|
|
180
182
|
path = path.replace(/^\./, '');
|
|
@@ -207,7 +209,7 @@ function objectGet(obj, path, strict = false) {
|
|
|
207
209
|
* 深拷贝堪称完全体 即:任何类型的数据都会被深拷贝
|
|
208
210
|
* @param {AnyObject | AnyArray} obj
|
|
209
211
|
* @param {WeakMap} map
|
|
210
|
-
* @
|
|
212
|
+
* @returns {AnyObject | AnyArray}
|
|
211
213
|
*/
|
|
212
214
|
function cloneDeep(obj, map = new WeakMap()) {
|
|
213
215
|
if (obj instanceof Date)
|
package/lib/cjs/path.js
CHANGED
package/lib/cjs/qs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -14,7 +14,7 @@ var type = require('./type.js');
|
|
|
14
14
|
* @param {string} queryString
|
|
15
15
|
* @returns {Params}
|
|
16
16
|
*/
|
|
17
|
-
|
|
17
|
+
function qsParse(queryString) {
|
|
18
18
|
const params = new URLSearchParams(queryString);
|
|
19
19
|
const result = {};
|
|
20
20
|
for (const [key, val] of params.entries()) {
|
|
@@ -28,7 +28,7 @@ const qsParse = (queryString) => {
|
|
|
28
28
|
result[key] = params.getAll(key);
|
|
29
29
|
}
|
|
30
30
|
return result;
|
|
31
|
-
}
|
|
31
|
+
}
|
|
32
32
|
const defaultReplacer = (val) => {
|
|
33
33
|
if (type.isString(val))
|
|
34
34
|
return val;
|
|
@@ -46,7 +46,7 @@ const defaultReplacer = (val) => {
|
|
|
46
46
|
* @param {Replacer} replacer
|
|
47
47
|
* @returns {string}
|
|
48
48
|
*/
|
|
49
|
-
|
|
49
|
+
function qsStringify(query, replacer = defaultReplacer) {
|
|
50
50
|
const params = new URLSearchParams();
|
|
51
51
|
object.objectEach(query, (val, key) => {
|
|
52
52
|
if (type.isArray(val)) {
|
|
@@ -65,7 +65,7 @@ const qsStringify = (query, replacer = defaultReplacer) => {
|
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
67
|
return params.toString();
|
|
68
|
-
}
|
|
68
|
+
}
|
|
69
69
|
|
|
70
70
|
exports.qsParse = qsParse;
|
|
71
71
|
exports.qsStringify = qsStringify;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
|
+
* (c) 2023-2023 chandq
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
var string = require('./string.js');
|
|
10
|
+
var type = require('./type.js');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 随机整数
|
|
14
|
+
* @param {number} min
|
|
15
|
+
* @param {number} max
|
|
16
|
+
* @returns {number}
|
|
17
|
+
*/
|
|
18
|
+
const randomNumber = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);
|
|
19
|
+
const STRING_POOL = `${string.STRING_ARABIC_NUMERALS}${string.STRING_UPPERCASE_ALPHA}${string.STRING_LOWERCASE_ALPHA}`;
|
|
20
|
+
/**
|
|
21
|
+
* 随机字符串
|
|
22
|
+
* @param {number | string} length
|
|
23
|
+
* @param {string} pool
|
|
24
|
+
* @returns {string}
|
|
25
|
+
*/
|
|
26
|
+
const randomString = (length, pool) => {
|
|
27
|
+
let _length = 0;
|
|
28
|
+
let _pool = STRING_POOL;
|
|
29
|
+
if (type.isString(pool)) {
|
|
30
|
+
_length = length;
|
|
31
|
+
_pool = pool;
|
|
32
|
+
}
|
|
33
|
+
else if (type.isNumber(length)) {
|
|
34
|
+
_length = length;
|
|
35
|
+
}
|
|
36
|
+
else if (type.isString(length)) {
|
|
37
|
+
_pool = length;
|
|
38
|
+
}
|
|
39
|
+
let times = Math.max(_length, 1);
|
|
40
|
+
let result = '';
|
|
41
|
+
const min = 0;
|
|
42
|
+
const max = _pool.length - 1;
|
|
43
|
+
if (max < 2)
|
|
44
|
+
throw new Error('字符串池长度不能少于 2');
|
|
45
|
+
while (times--) {
|
|
46
|
+
const index = randomNumber(min, max);
|
|
47
|
+
result += _pool[index];
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* 优先浏览器原生能力获取 UUID v4
|
|
53
|
+
* @returns {string}
|
|
54
|
+
*/
|
|
55
|
+
function randomUuid() {
|
|
56
|
+
if (typeof URL === 'undefined' || !URL.createObjectURL || typeof Blob === 'undefined') {
|
|
57
|
+
const hex = '0123456789abcdef';
|
|
58
|
+
const model = 'xxxxxxxx-xxxx-4xxx-xxxx-xxxxxxxxxxxx';
|
|
59
|
+
let str = '';
|
|
60
|
+
for (let i = 0; i < model.length; i++) {
|
|
61
|
+
const rnd = randomNumber(0, 15);
|
|
62
|
+
str += model[i] == '-' || model[i] == '4' ? model[i] : hex[rnd];
|
|
63
|
+
}
|
|
64
|
+
return str;
|
|
65
|
+
}
|
|
66
|
+
return /[^/]+$/.exec(URL.createObjectURL(new Blob()).slice())[0];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
exports.STRING_POOL = STRING_POOL;
|
|
70
|
+
exports.randomNumber = randomNumber;
|
|
71
|
+
exports.randomString = randomString;
|
|
72
|
+
exports.randomUuid = randomUuid;
|
package/lib/cjs/string.js
CHANGED
|
@@ -1,35 +1,37 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
+
var type = require('./type.js');
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
12
|
* 将字符串转换为驼峰格式
|
|
11
13
|
* @param {string} string
|
|
12
14
|
* @param {boolean} [bigger] 是否大写第一个字母
|
|
13
15
|
* @returns {string}
|
|
14
16
|
*/
|
|
15
|
-
|
|
17
|
+
function stringCamelCase(string, bigger) {
|
|
16
18
|
let string2 = string;
|
|
17
19
|
if (bigger) {
|
|
18
20
|
string2 = string.replace(/^./, origin => origin.toUpperCase());
|
|
19
21
|
}
|
|
20
22
|
const HUMP_RE = /[\s_-](.)/g;
|
|
21
23
|
return string2.replace(HUMP_RE, (orign, char) => char.toUpperCase());
|
|
22
|
-
}
|
|
24
|
+
}
|
|
23
25
|
/**
|
|
24
26
|
* 将字符串转换为连字格式
|
|
25
27
|
* @param {string} string
|
|
26
28
|
* @param {string} [separator] 分隔符,默认是"-"(短横线)
|
|
27
29
|
* @returns {string}
|
|
28
30
|
*/
|
|
29
|
-
|
|
31
|
+
function stringKebabCase(string, separator = '-') {
|
|
30
32
|
const string2 = string.replace(/^./, origin => origin.toLowerCase());
|
|
31
33
|
return string2.replace(/[A-Z]/g, origin => `${separator}${origin.toLowerCase()}`);
|
|
32
|
-
}
|
|
34
|
+
}
|
|
33
35
|
const STRING_ARABIC_NUMERALS = '0123456789';
|
|
34
36
|
const STRING_LOWERCASE_ALPHA = 'abcdefghijklmnopqrstuvwxyz';
|
|
35
37
|
const STRING_UPPERCASE_ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
@@ -45,7 +47,7 @@ const placeholderRE = /%[%sdo]/g;
|
|
|
45
47
|
* @param args
|
|
46
48
|
* @returns {string}
|
|
47
49
|
*/
|
|
48
|
-
|
|
50
|
+
function stringFormat(string, ...args) {
|
|
49
51
|
let index = 0;
|
|
50
52
|
const result = string.replace(placeholderRE, (origin) => {
|
|
51
53
|
const arg = args[index++];
|
|
@@ -63,7 +65,7 @@ const stringFormat = (string, ...args) => {
|
|
|
63
65
|
}
|
|
64
66
|
});
|
|
65
67
|
return [result, ...args.splice(index).map(String)].join(' ');
|
|
66
|
-
}
|
|
68
|
+
}
|
|
67
69
|
const ev = (expression, data) => {
|
|
68
70
|
try {
|
|
69
71
|
// eslint-disable-next-line @typescript-eslint/no-implied-eval,@typescript-eslint/no-unsafe-return
|
|
@@ -122,10 +124,41 @@ const stringEscapeHtml = (html) => {
|
|
|
122
124
|
* @returns {string}
|
|
123
125
|
*/
|
|
124
126
|
const stringFill = (length, value = ' ') => new Array(length).fill(value).join('');
|
|
127
|
+
/**
|
|
128
|
+
* 字符串的像素宽度
|
|
129
|
+
* @param {string} str 目标字符串
|
|
130
|
+
* @param {number} fontSize 字符串字体大小
|
|
131
|
+
* @param {boolean} isRemoveDom 计算后是否移除中间dom元素
|
|
132
|
+
* @returns {*}
|
|
133
|
+
*/
|
|
134
|
+
function getStrWidthPx(str, fontSize = 14, isRemoveDom = false) {
|
|
135
|
+
let strWidth = 0;
|
|
136
|
+
console.assert(type.isString(str), `${str} 不是有效的字符串`);
|
|
137
|
+
if (type.isString(str) && str.length > 0) {
|
|
138
|
+
let getEle = document.querySelector('#getStrWidth1494304949567');
|
|
139
|
+
if (!getEle) {
|
|
140
|
+
const _ele = document.createElement('span');
|
|
141
|
+
_ele.id = 'getStrWidth1494304949567';
|
|
142
|
+
_ele.style.fontSize = fontSize + 'px';
|
|
143
|
+
_ele.style.whiteSpace = 'nowrap';
|
|
144
|
+
_ele.style.visibility = 'hidden';
|
|
145
|
+
_ele.textContent = str;
|
|
146
|
+
document.body.appendChild(_ele);
|
|
147
|
+
getEle = _ele;
|
|
148
|
+
}
|
|
149
|
+
getEle.textContent = str;
|
|
150
|
+
strWidth = getEle.offsetWidth;
|
|
151
|
+
if (isRemoveDom) {
|
|
152
|
+
document.body.appendChild(getEle);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return strWidth;
|
|
156
|
+
}
|
|
125
157
|
|
|
126
158
|
exports.STRING_ARABIC_NUMERALS = STRING_ARABIC_NUMERALS;
|
|
127
159
|
exports.STRING_LOWERCASE_ALPHA = STRING_LOWERCASE_ALPHA;
|
|
128
160
|
exports.STRING_UPPERCASE_ALPHA = STRING_UPPERCASE_ALPHA;
|
|
161
|
+
exports.getStrWidthPx = getStrWidthPx;
|
|
129
162
|
exports.stringAssign = stringAssign;
|
|
130
163
|
exports.stringCamelCase = stringCamelCase;
|
|
131
164
|
exports.stringEscapeHtml = stringEscapeHtml;
|
package/lib/cjs/type.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js
|
|
2
|
+
* sculp-js v1.0.0
|
|
3
3
|
* (c) 2023-2023 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* 判断任意值的数据类型
|
|
13
|
+
* @param {unknown} any
|
|
14
|
+
* @returns {string}
|
|
15
|
+
*/
|
|
11
16
|
const typeIs = (any) => Object.prototype.toString.call(any).slice(8, -1);
|
|
12
17
|
// 基本数据类型判断
|
|
13
18
|
const isString = (any) => typeof any === 'string';
|
|
@@ -21,7 +26,11 @@ const isPrimitive = (any) => any === null || typeof any !== 'object';
|
|
|
21
26
|
// 复合数据类型判断
|
|
22
27
|
const isObject = (any) => typeIs(any) === 'Object';
|
|
23
28
|
const isArray = (any) => Array.isArray(any);
|
|
24
|
-
|
|
29
|
+
/**
|
|
30
|
+
* 判断是否为函数
|
|
31
|
+
* @param {unknown} any
|
|
32
|
+
* @returns {boolean}
|
|
33
|
+
*/
|
|
25
34
|
const isFunction = (any) => typeof any === 'function';
|
|
26
35
|
// 对象类型判断
|
|
27
36
|
const isNaN = (any) => Number.isNaN(any);
|
|
@@ -45,3 +54,4 @@ exports.isRegExp = isRegExp;
|
|
|
45
54
|
exports.isString = isString;
|
|
46
55
|
exports.isSymbol = isSymbol;
|
|
47
56
|
exports.isUndefined = isUndefined;
|
|
57
|
+
exports.typeIs = typeIs;
|