sculp-js 1.2.1 → 1.3.1

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 (52) hide show
  1. package/lib/cjs/array.js +2 -2
  2. package/lib/cjs/async.js +2 -2
  3. package/lib/cjs/clipboard.js +2 -2
  4. package/lib/cjs/cookie.js +2 -2
  5. package/lib/cjs/date.js +2 -2
  6. package/lib/cjs/dom.js +2 -2
  7. package/lib/cjs/download.js +2 -2
  8. package/lib/cjs/easing.js +2 -2
  9. package/lib/cjs/file.js +126 -2
  10. package/lib/cjs/func.js +2 -2
  11. package/lib/cjs/index.js +9 -2
  12. package/lib/cjs/number.js +2 -2
  13. package/lib/cjs/object.js +2 -2
  14. package/lib/cjs/path.js +2 -2
  15. package/lib/cjs/qs.js +2 -2
  16. package/lib/cjs/random.js +2 -2
  17. package/lib/cjs/string.js +2 -2
  18. package/lib/cjs/tooltip.js +2 -2
  19. package/lib/cjs/tree.js +6 -8
  20. package/lib/cjs/type.js +6 -2
  21. package/lib/cjs/unique.js +2 -2
  22. package/lib/cjs/url.js +2 -2
  23. package/lib/cjs/watermark.js +2 -2
  24. package/lib/cjs/we-decode.js +107 -0
  25. package/lib/es/array.js +2 -2
  26. package/lib/es/async.js +2 -2
  27. package/lib/es/clipboard.js +2 -2
  28. package/lib/es/cookie.js +2 -2
  29. package/lib/es/date.js +2 -2
  30. package/lib/es/dom.js +2 -2
  31. package/lib/es/download.js +2 -2
  32. package/lib/es/easing.js +2 -2
  33. package/lib/es/file.js +125 -3
  34. package/lib/es/func.js +2 -2
  35. package/lib/es/index.js +5 -4
  36. package/lib/es/number.js +2 -2
  37. package/lib/es/object.js +2 -2
  38. package/lib/es/path.js +2 -2
  39. package/lib/es/qs.js +2 -2
  40. package/lib/es/random.js +2 -2
  41. package/lib/es/string.js +2 -2
  42. package/lib/es/tooltip.js +2 -2
  43. package/lib/es/tree.js +6 -8
  44. package/lib/es/type.js +6 -3
  45. package/lib/es/unique.js +2 -2
  46. package/lib/es/url.js +2 -2
  47. package/lib/es/watermark.js +2 -2
  48. package/lib/es/we-decode.js +103 -0
  49. package/lib/index.d.ts +35 -1
  50. package/lib/umd/index.js +231 -8
  51. package/package.json +3 -1
  52. package/lib/tsdoc-metadata.json +0 -11
package/lib/umd/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * sculp-js v1.2.1
3
- * (c) 2023-2023 chandq
2
+ * sculp-js v1.3.0
3
+ * (c) 2023-2024 chandq
4
4
  * Released under the MIT License.
5
5
  */
6
6
 
@@ -25,6 +25,9 @@
25
25
  const isUndefined = (any) => typeof any === 'undefined';
26
26
  const isNull = (any) => any === null;
27
27
  const isPrimitive = (any) => any === null || typeof any !== 'object';
28
+ function isNullOrUnDef(val) {
29
+ return isUndefined(val) || isNull(val);
30
+ }
28
31
  // 复合数据类型判断
29
32
  const isObject = (any) => typeIs(any) === 'Object';
30
33
  const isArray = (any) => Array.isArray(any);
@@ -1274,6 +1277,109 @@
1274
1277
  });
1275
1278
  }
1276
1279
 
1280
+ const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
1281
+ // eslint-disable-next-line
1282
+ const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
1283
+ /**
1284
+ * 字符串编码成Base64 (适用于任何环境,包括小程序)
1285
+ * @param {string} string
1286
+ * @return {string}
1287
+ */
1288
+ function weBtoa(string) {
1289
+ // 同window.btoa: 字符串编码成Base64
1290
+ string = String(string);
1291
+ let bitmap, a, b, c, result = '', i = 0;
1292
+ const rest = string.length % 3;
1293
+ for (; i < string.length;) {
1294
+ if ((a = string.charCodeAt(i++)) > 255 || (b = string.charCodeAt(i++)) > 255 || (c = string.charCodeAt(i++)) > 255)
1295
+ throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.");
1296
+ bitmap = (a << 16) | (b << 8) | c;
1297
+ result +=
1298
+ b64.charAt((bitmap >> 18) & 63) +
1299
+ b64.charAt((bitmap >> 12) & 63) +
1300
+ b64.charAt((bitmap >> 6) & 63) +
1301
+ b64.charAt(bitmap & 63);
1302
+ }
1303
+ return rest ? result.slice(0, rest - 3) + '==='.substring(rest) : result;
1304
+ }
1305
+ /**
1306
+ * Base64解码为原始字符串(适用于任何环境,包括小程序)
1307
+ * @param {string} string
1308
+ * @return {string}
1309
+ */
1310
+ function weAtob(string) {
1311
+ // 同window.atob: Base64解码为原始字符串
1312
+ string = String(string).replace(/[\t\n\f\r ]+/g, '');
1313
+ if (!b64re.test(string))
1314
+ throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
1315
+ string += '=='.slice(2 - (string.length & 3));
1316
+ let bitmap, result = '', r1, r2, i = 0;
1317
+ for (; i < string.length;) {
1318
+ bitmap =
1319
+ (b64.indexOf(string.charAt(i++)) << 18) |
1320
+ (b64.indexOf(string.charAt(i++)) << 12) |
1321
+ ((r1 = b64.indexOf(string.charAt(i++))) << 6) |
1322
+ (r2 = b64.indexOf(string.charAt(i++)));
1323
+ result +=
1324
+ r1 === 64
1325
+ ? String.fromCharCode((bitmap >> 16) & 255)
1326
+ : r2 === 64
1327
+ ? String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255)
1328
+ : String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255, bitmap & 255);
1329
+ }
1330
+ return result;
1331
+ }
1332
+ function b64DecodeUnicode(str) {
1333
+ return decodeURIComponent(exports.weAtob(str).replace(/(.)/g, function (p) {
1334
+ let code = p.charCodeAt(0).toString(16).toUpperCase();
1335
+ if (code.length < 2) {
1336
+ code = '0' + code;
1337
+ }
1338
+ return '%' + code;
1339
+ }));
1340
+ }
1341
+ function base64_url_decode(str) {
1342
+ let output = str.replace(/-/g, '+').replace(/_/g, '/');
1343
+ switch (output.length % 4) {
1344
+ case 0:
1345
+ break;
1346
+ case 2:
1347
+ output += '==';
1348
+ break;
1349
+ case 3:
1350
+ output += '=';
1351
+ break;
1352
+ default:
1353
+ throw new Error('Illegal base64url string!');
1354
+ }
1355
+ try {
1356
+ return b64DecodeUnicode(output);
1357
+ }
1358
+ catch (err) {
1359
+ return exports.weAtob(output);
1360
+ }
1361
+ }
1362
+ function weAppJwtDecode(token, options) {
1363
+ if (typeof token !== 'string') {
1364
+ throw new Error('Invalid token specified');
1365
+ }
1366
+ options = options || {};
1367
+ const pos = options.header === true ? 0 : 1;
1368
+ try {
1369
+ return JSON.parse(base64_url_decode(token.split('.')[pos]));
1370
+ }
1371
+ catch (e) {
1372
+ throw new Error('Invalid token specified: ' + e.message);
1373
+ }
1374
+ }
1375
+
1376
+ /**
1377
+ * 判断是否支持canvas
1378
+ * @returns {boolean}
1379
+ */
1380
+ function supportCanvas() {
1381
+ return !!document.createElement('canvas').getContext;
1382
+ }
1277
1383
  /**
1278
1384
  * 选择本地文件
1279
1385
  * @param {string} accept 上传的文件类型,用于过滤
@@ -1295,6 +1401,119 @@
1295
1401
  };
1296
1402
  return inputObj;
1297
1403
  }
1404
+ /**
1405
+ * Web端:等比例压缩图片批量处理 (size小于200KB,不压缩)
1406
+ * @param {File | FileList} file 文件
1407
+ * @param {ICompressOptions} options
1408
+ * @returns {Promise<object> | undefined}
1409
+ */
1410
+ function compressImg(file, options) {
1411
+ console.assert(file instanceof File || file instanceof FileList, `${file} 必须是File或FileList类型`);
1412
+ console.assert(supportCanvas(), `当前环境不支持 Canvas`);
1413
+ let targetQuality = 0.52;
1414
+ if (file instanceof File) {
1415
+ const sizeKB = +parseInt((file.size / 1024).toFixed(2));
1416
+ if (sizeKB < 1 * 1024) {
1417
+ targetQuality = 0.85;
1418
+ }
1419
+ else if (sizeKB >= 1 * 1024 && sizeKB < 5 * 1024) {
1420
+ targetQuality = 0.62;
1421
+ }
1422
+ else if (sizeKB >= 5 * 1024) {
1423
+ targetQuality = 0.52;
1424
+ }
1425
+ }
1426
+ if (options.quality) {
1427
+ targetQuality = options.quality;
1428
+ }
1429
+ if (file instanceof FileList) {
1430
+ return Promise.all(Array.from(file).map(el => compressImg(el, { mime: options.mime, quality: targetQuality }))); // 如果是 file 数组返回 Promise 数组
1431
+ }
1432
+ else if (file instanceof File) {
1433
+ return new Promise(resolve => {
1434
+ const sizeKB = +parseInt((file.size / 1024).toFixed(2));
1435
+ if (+(file.size / 1024).toFixed(2) < 200) {
1436
+ resolve({
1437
+ file: file
1438
+ });
1439
+ }
1440
+ else {
1441
+ const reader = new FileReader(); // 创建 FileReader
1442
+ // @ts-ignore
1443
+ reader.onload = ({ target: { result: src } }) => {
1444
+ const image = new Image(); // 创建 img 元素
1445
+ image.onload = () => {
1446
+ const canvas = document.createElement('canvas'); // 创建 canvas 元素
1447
+ const context = canvas.getContext('2d');
1448
+ let targetWidth = image.width;
1449
+ let targetHeight = image.height;
1450
+ const originWidth = image.width;
1451
+ const originHeight = image.height;
1452
+ if (1 * 1024 <= sizeKB && sizeKB < 10 * 1024) {
1453
+ const maxWidth = 1600, maxHeight = 1600;
1454
+ targetWidth = originWidth;
1455
+ targetHeight = originHeight;
1456
+ // 图片尺寸超过的限制
1457
+ if (originWidth > maxWidth || originHeight > maxHeight) {
1458
+ if (originWidth / originHeight > maxWidth / maxHeight) {
1459
+ // 更宽,按照宽度限定尺寸
1460
+ targetWidth = maxWidth;
1461
+ targetHeight = Math.round(maxWidth * (originHeight / originWidth));
1462
+ }
1463
+ else {
1464
+ targetHeight = maxHeight;
1465
+ targetWidth = Math.round(maxHeight * (originWidth / originHeight));
1466
+ }
1467
+ }
1468
+ }
1469
+ if (10 * 1024 <= sizeKB && sizeKB <= 20 * 1024) {
1470
+ const maxWidth = 1400, maxHeight = 1400;
1471
+ targetWidth = originWidth;
1472
+ targetHeight = originHeight;
1473
+ // 图片尺寸超过的限制
1474
+ if (originWidth > maxWidth || originHeight > maxHeight) {
1475
+ if (originWidth / originHeight > maxWidth / maxHeight) {
1476
+ // 更宽,按照宽度限定尺寸
1477
+ targetWidth = maxWidth;
1478
+ targetHeight = Math.round(maxWidth * (originHeight / originWidth));
1479
+ }
1480
+ else {
1481
+ targetHeight = maxHeight;
1482
+ targetWidth = Math.round(maxHeight * (originWidth / originHeight));
1483
+ }
1484
+ }
1485
+ }
1486
+ canvas.width = targetWidth;
1487
+ canvas.height = targetHeight;
1488
+ context.clearRect(0, 0, targetWidth, targetHeight);
1489
+ context.drawImage(image, 0, 0, targetWidth, targetHeight); // 绘制 canvas
1490
+ const canvasURL = canvas.toDataURL(options.mime, targetQuality);
1491
+ const buffer = weAtob(canvasURL.split(',')[1]);
1492
+ let length = buffer.length;
1493
+ const bufferArray = new Uint8Array(new ArrayBuffer(length));
1494
+ while (length--) {
1495
+ bufferArray[length] = buffer.charCodeAt(length);
1496
+ }
1497
+ const miniFile = new File([bufferArray], file.name, {
1498
+ type: options.mime
1499
+ });
1500
+ resolve({
1501
+ file: miniFile,
1502
+ bufferArray,
1503
+ origin: file,
1504
+ beforeSrc: src,
1505
+ afterSrc: canvasURL,
1506
+ beforeKB: Number((file.size / 1024).toFixed(2)),
1507
+ afterKB: Number((miniFile.size / 1024).toFixed(2))
1508
+ });
1509
+ };
1510
+ image.src = src;
1511
+ };
1512
+ reader.readAsDataURL(file);
1513
+ }
1514
+ });
1515
+ }
1516
+ }
1298
1517
 
1299
1518
  /*
1300
1519
  * @created: Saturday, 2020-04-18 14:38:23
@@ -1833,8 +2052,8 @@
1833
2052
  * @returns {*}
1834
2053
  */
1835
2054
  function forEachDeep(tree, iterator, children = 'children', isReverse = false) {
1836
- let level = 0, isBreak = false;
1837
- const walk = (arr, parent) => {
2055
+ let isBreak = false;
2056
+ const walk = (arr, parent, level = 0) => {
1838
2057
  if (isReverse) {
1839
2058
  for (let i = arr.length - 1; i >= 0; i--) {
1840
2059
  if (isBreak) {
@@ -1850,9 +2069,8 @@
1850
2069
  }
1851
2070
  // @ts-ignore
1852
2071
  if (arr[i] && Array.isArray(arr[i][children])) {
1853
- ++level;
1854
2072
  // @ts-ignore
1855
- walk(arr[i][children], arr[i]);
2073
+ walk(arr[i][children], arr[i], level + 1);
1856
2074
  }
1857
2075
  }
1858
2076
  }
@@ -1871,9 +2089,8 @@
1871
2089
  }
1872
2090
  // @ts-ignore
1873
2091
  if (arr[i] && Array.isArray(arr[i][children])) {
1874
- ++level;
1875
2092
  // @ts-ignore
1876
- walk(arr[i][children], arr[i]);
2093
+ walk(arr[i][children], arr[i], level + 1);
1877
2094
  }
1878
2095
  }
1879
2096
  }
@@ -2111,6 +2328,7 @@
2111
2328
  exports.calculateDateTime = calculateDateTime;
2112
2329
  exports.chooseLocalFile = chooseLocalFile;
2113
2330
  exports.cloneDeep = cloneDeep;
2331
+ exports.compressImg = compressImg;
2114
2332
  exports.cookieDel = cookieDel;
2115
2333
  exports.cookieGet = cookieGet;
2116
2334
  exports.cookieSet = cookieSet;
@@ -2143,6 +2361,7 @@
2143
2361
  exports.isFunction = isFunction;
2144
2362
  exports.isNaN = isNaN;
2145
2363
  exports.isNull = isNull;
2364
+ exports.isNullOrUnDef = isNullOrUnDef;
2146
2365
  exports.isNumber = isNumber;
2147
2366
  exports.isObject = isObject;
2148
2367
  exports.isPlainObject = isPlainObject;
@@ -2184,6 +2403,7 @@
2184
2403
  exports.stringFill = stringFill;
2185
2404
  exports.stringFormat = stringFormat;
2186
2405
  exports.stringKebabCase = stringKebabCase;
2406
+ exports.supportCanvas = supportCanvas;
2187
2407
  exports.throttle = throttle;
2188
2408
  exports.tooltipEvent = tooltipEvent;
2189
2409
  exports.typeIs = typeIs;
@@ -2194,5 +2414,8 @@
2194
2414
  exports.urlSetParams = urlSetParams;
2195
2415
  exports.urlStringify = urlStringify;
2196
2416
  exports.wait = wait;
2417
+ exports.weAppJwtDecode = weAppJwtDecode;
2418
+ exports.weAtob = weAtob;
2419
+ exports.weBtoa = weBtoa;
2197
2420
 
2198
2421
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sculp-js",
3
- "version": "1.2.1",
3
+ "version": "1.3.1",
4
4
  "packageManager": "npm@8.19.2",
5
5
  "description": "js工具库",
6
6
  "scripts": {
@@ -72,8 +72,10 @@
72
72
  "eslint-config-prettier": "^9.0.0",
73
73
  "eslint-config-standard": "^17.1.0",
74
74
  "eslint-import-resolver-webpack": "^0.13.7",
75
+ "eslint-plugin-eslint-plugin": "^5.5.1",
75
76
  "eslint-plugin-import": "^2.28.1",
76
77
  "eslint-plugin-jest": "^27.4.2",
78
+ "eslint-plugin-node": "^11.1.0",
77
79
  "eslint-plugin-prettier": "^5.0.1",
78
80
  "eslint-plugin-standard": "^5.0.0",
79
81
  "husky": "^8.0.3",
@@ -1,11 +0,0 @@
1
- // This file is read by tools that parse documentation comments conforming to the TSDoc standard.
2
- // It should be published with your NPM package. It should not be tracked by Git.
3
- {
4
- "tsdocVersion": "0.12",
5
- "toolPackages": [
6
- {
7
- "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.38.3"
9
- }
10
- ]
11
- }