sculp-js 1.2.0 → 1.3.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/README.md +6 -1
- package/lib/cjs/array.js +2 -2
- package/lib/cjs/async.js +2 -2
- package/lib/cjs/clipboard.js +2 -2
- package/lib/cjs/cookie.js +2 -2
- package/lib/cjs/date.js +2 -2
- package/lib/cjs/dom.js +2 -2
- package/lib/cjs/download.js +2 -2
- package/lib/cjs/easing.js +2 -2
- package/lib/cjs/file.js +126 -2
- package/lib/cjs/func.js +2 -2
- package/lib/cjs/index.js +10 -2
- package/lib/cjs/number.js +2 -2
- package/lib/cjs/object.js +2 -2
- package/lib/cjs/path.js +2 -2
- package/lib/cjs/qs.js +2 -2
- package/lib/cjs/random.js +2 -2
- package/lib/cjs/string.js +2 -2
- package/lib/cjs/tooltip.js +2 -2
- package/lib/cjs/tree.js +74 -3
- package/lib/cjs/type.js +6 -2
- package/lib/cjs/unique.js +2 -2
- package/lib/cjs/url.js +2 -2
- package/lib/cjs/watermark.js +2 -2
- package/lib/cjs/we-decode.js +107 -0
- package/lib/es/array.js +2 -2
- package/lib/es/async.js +2 -2
- package/lib/es/clipboard.js +2 -2
- package/lib/es/cookie.js +2 -2
- package/lib/es/date.js +2 -2
- package/lib/es/dom.js +2 -2
- package/lib/es/download.js +2 -2
- package/lib/es/easing.js +2 -2
- package/lib/es/file.js +125 -3
- package/lib/es/func.js +2 -2
- package/lib/es/index.js +6 -5
- package/lib/es/number.js +2 -2
- package/lib/es/object.js +2 -2
- package/lib/es/path.js +2 -2
- package/lib/es/qs.js +2 -2
- package/lib/es/random.js +2 -2
- package/lib/es/string.js +2 -2
- package/lib/es/tooltip.js +2 -2
- package/lib/es/tree.js +74 -4
- package/lib/es/type.js +6 -3
- package/lib/es/unique.js +2 -2
- package/lib/es/url.js +2 -2
- package/lib/es/watermark.js +2 -2
- package/lib/es/we-decode.js +103 -0
- package/lib/index.d.ts +45 -2
- package/lib/umd/index.js +299 -3
- package/package.json +6 -3
- package/lib/tsdoc-metadata.json +0 -11
package/README.md
CHANGED
|
@@ -28,9 +28,14 @@
|
|
|
28
28
|
|
|
29
29
|
- arrayLike 判断类数组
|
|
30
30
|
- arrayEachAsync 异步遍历数组,可中断,支持倒序
|
|
31
|
-
|
|
31
|
+
|
|
32
|
+
- Tree
|
|
33
|
+
|
|
34
|
+
- forEachDeep 高性能的深度优先遍历函数, 支持continue、break,可定制id、children
|
|
35
|
+
- forEachMap 高性能的深度优先遍历的Map函数, 支持continue、break,可定制id、children
|
|
32
36
|
- searchTreeById 在树中找到 id 为某个值的节点,并返回上游的所有父级节点
|
|
33
37
|
- buildTree 根据 id 与 parentId 从对象数组中构建对应的树
|
|
38
|
+
- formatTree 高性能的数组转树函数
|
|
34
39
|
|
|
35
40
|
- Object
|
|
36
41
|
|
package/lib/cjs/array.js
CHANGED
package/lib/cjs/async.js
CHANGED
package/lib/cjs/clipboard.js
CHANGED
package/lib/cjs/cookie.js
CHANGED
package/lib/cjs/date.js
CHANGED
package/lib/cjs/dom.js
CHANGED
package/lib/cjs/download.js
CHANGED
package/lib/cjs/easing.js
CHANGED
package/lib/cjs/file.js
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.
|
|
3
|
-
* (c) 2023-
|
|
2
|
+
* sculp-js v1.3.0
|
|
3
|
+
* (c) 2023-2024 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
+
var weDecode = require('./we-decode.js');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 判断是否支持canvas
|
|
13
|
+
* @returns {boolean}
|
|
14
|
+
*/
|
|
15
|
+
function supportCanvas() {
|
|
16
|
+
return !!document.createElement('canvas').getContext;
|
|
17
|
+
}
|
|
9
18
|
/**
|
|
10
19
|
* 选择本地文件
|
|
11
20
|
* @param {string} accept 上传的文件类型,用于过滤
|
|
@@ -27,5 +36,120 @@ function chooseLocalFile(accept, changeCb) {
|
|
|
27
36
|
};
|
|
28
37
|
return inputObj;
|
|
29
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Web端:等比例压缩图片批量处理 (size小于200KB,不压缩)
|
|
41
|
+
* @param {File | FileList} file 文件
|
|
42
|
+
* @param {ICompressOptions} options
|
|
43
|
+
* @returns {Promise<object> | undefined}
|
|
44
|
+
*/
|
|
45
|
+
function compressImg(file, options) {
|
|
46
|
+
console.assert(file instanceof File || file instanceof FileList, `${file} 必须是File或FileList类型`);
|
|
47
|
+
console.assert(supportCanvas(), `当前环境不支持 Canvas`);
|
|
48
|
+
let targetQuality = 0.52;
|
|
49
|
+
if (file instanceof File) {
|
|
50
|
+
const sizeKB = +parseInt((file.size / 1024).toFixed(2));
|
|
51
|
+
if (sizeKB < 1 * 1024) {
|
|
52
|
+
targetQuality = 0.85;
|
|
53
|
+
}
|
|
54
|
+
else if (sizeKB >= 1 * 1024 && sizeKB < 5 * 1024) {
|
|
55
|
+
targetQuality = 0.62;
|
|
56
|
+
}
|
|
57
|
+
else if (sizeKB >= 5 * 1024) {
|
|
58
|
+
targetQuality = 0.52;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (options.quality) {
|
|
62
|
+
targetQuality = options.quality;
|
|
63
|
+
}
|
|
64
|
+
if (file instanceof FileList) {
|
|
65
|
+
return Promise.all(Array.from(file).map(el => compressImg(el, { mime: options.mime, quality: targetQuality }))); // 如果是 file 数组返回 Promise 数组
|
|
66
|
+
}
|
|
67
|
+
else if (file instanceof File) {
|
|
68
|
+
return new Promise(resolve => {
|
|
69
|
+
const sizeKB = +parseInt((file.size / 1024).toFixed(2));
|
|
70
|
+
if (+(file.size / 1024).toFixed(2) < 200) {
|
|
71
|
+
resolve({
|
|
72
|
+
file: file
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const reader = new FileReader(); // 创建 FileReader
|
|
77
|
+
// @ts-ignore
|
|
78
|
+
reader.onload = ({ target: { result: src } }) => {
|
|
79
|
+
const image = new Image(); // 创建 img 元素
|
|
80
|
+
image.onload = () => {
|
|
81
|
+
const canvas = document.createElement('canvas'); // 创建 canvas 元素
|
|
82
|
+
const context = canvas.getContext('2d');
|
|
83
|
+
let targetWidth = image.width;
|
|
84
|
+
let targetHeight = image.height;
|
|
85
|
+
const originWidth = image.width;
|
|
86
|
+
const originHeight = image.height;
|
|
87
|
+
if (1 * 1024 <= sizeKB && sizeKB < 10 * 1024) {
|
|
88
|
+
const maxWidth = 1600, maxHeight = 1600;
|
|
89
|
+
targetWidth = originWidth;
|
|
90
|
+
targetHeight = originHeight;
|
|
91
|
+
// 图片尺寸超过的限制
|
|
92
|
+
if (originWidth > maxWidth || originHeight > maxHeight) {
|
|
93
|
+
if (originWidth / originHeight > maxWidth / maxHeight) {
|
|
94
|
+
// 更宽,按照宽度限定尺寸
|
|
95
|
+
targetWidth = maxWidth;
|
|
96
|
+
targetHeight = Math.round(maxWidth * (originHeight / originWidth));
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
targetHeight = maxHeight;
|
|
100
|
+
targetWidth = Math.round(maxHeight * (originWidth / originHeight));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (10 * 1024 <= sizeKB && sizeKB <= 20 * 1024) {
|
|
105
|
+
const maxWidth = 1400, maxHeight = 1400;
|
|
106
|
+
targetWidth = originWidth;
|
|
107
|
+
targetHeight = originHeight;
|
|
108
|
+
// 图片尺寸超过的限制
|
|
109
|
+
if (originWidth > maxWidth || originHeight > maxHeight) {
|
|
110
|
+
if (originWidth / originHeight > maxWidth / maxHeight) {
|
|
111
|
+
// 更宽,按照宽度限定尺寸
|
|
112
|
+
targetWidth = maxWidth;
|
|
113
|
+
targetHeight = Math.round(maxWidth * (originHeight / originWidth));
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
targetHeight = maxHeight;
|
|
117
|
+
targetWidth = Math.round(maxHeight * (originWidth / originHeight));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
canvas.width = targetWidth;
|
|
122
|
+
canvas.height = targetHeight;
|
|
123
|
+
context.clearRect(0, 0, targetWidth, targetHeight);
|
|
124
|
+
context.drawImage(image, 0, 0, targetWidth, targetHeight); // 绘制 canvas
|
|
125
|
+
const canvasURL = canvas.toDataURL(options.mime, targetQuality);
|
|
126
|
+
const buffer = weDecode.weAtob(canvasURL.split(',')[1]);
|
|
127
|
+
let length = buffer.length;
|
|
128
|
+
const bufferArray = new Uint8Array(new ArrayBuffer(length));
|
|
129
|
+
while (length--) {
|
|
130
|
+
bufferArray[length] = buffer.charCodeAt(length);
|
|
131
|
+
}
|
|
132
|
+
const miniFile = new File([bufferArray], file.name, {
|
|
133
|
+
type: options.mime
|
|
134
|
+
});
|
|
135
|
+
resolve({
|
|
136
|
+
file: miniFile,
|
|
137
|
+
bufferArray,
|
|
138
|
+
origin: file,
|
|
139
|
+
beforeSrc: src,
|
|
140
|
+
afterSrc: canvasURL,
|
|
141
|
+
beforeKB: Number((file.size / 1024).toFixed(2)),
|
|
142
|
+
afterKB: Number((miniFile.size / 1024).toFixed(2))
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
image.src = src;
|
|
146
|
+
};
|
|
147
|
+
reader.readAsDataURL(file);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
30
152
|
|
|
31
153
|
exports.chooseLocalFile = chooseLocalFile;
|
|
154
|
+
exports.compressImg = compressImg;
|
|
155
|
+
exports.supportCanvas = supportCanvas;
|
package/lib/cjs/func.js
CHANGED
package/lib/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.
|
|
3
|
-
* (c) 2023-
|
|
2
|
+
* sculp-js v1.3.0
|
|
3
|
+
* (c) 2023-2024 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -27,6 +27,7 @@ var number = require('./number.js');
|
|
|
27
27
|
var unique = require('./unique.js');
|
|
28
28
|
var tooltip = require('./tooltip.js');
|
|
29
29
|
var tree = require('./tree.js');
|
|
30
|
+
var weDecode = require('./we-decode.js');
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
|
|
@@ -93,6 +94,7 @@ exports.isError = type.isError;
|
|
|
93
94
|
exports.isFunction = type.isFunction;
|
|
94
95
|
exports.isNaN = type.isNaN;
|
|
95
96
|
exports.isNull = type.isNull;
|
|
97
|
+
exports.isNullOrUnDef = type.isNullOrUnDef;
|
|
96
98
|
exports.isNumber = type.isNumber;
|
|
97
99
|
exports.isObject = type.isObject;
|
|
98
100
|
exports.isPrimitive = type.isPrimitive;
|
|
@@ -108,6 +110,8 @@ exports.urlStringify = url.urlStringify;
|
|
|
108
110
|
exports.asyncMap = async.asyncMap;
|
|
109
111
|
exports.wait = async.wait;
|
|
110
112
|
exports.chooseLocalFile = file.chooseLocalFile;
|
|
113
|
+
exports.compressImg = file.compressImg;
|
|
114
|
+
exports.supportCanvas = file.supportCanvas;
|
|
111
115
|
exports.genCanvasWM = watermark.genCanvasWM;
|
|
112
116
|
exports.debounce = func.debounce;
|
|
113
117
|
exports.getGlobal = func.getGlobal;
|
|
@@ -128,5 +132,9 @@ exports.uniqueString = unique.uniqueString;
|
|
|
128
132
|
exports.tooltipEvent = tooltip.tooltipEvent;
|
|
129
133
|
exports.buildTree = tree.buildTree;
|
|
130
134
|
exports.forEachDeep = tree.forEachDeep;
|
|
135
|
+
exports.forEachMap = tree.forEachMap;
|
|
131
136
|
exports.formatTree = tree.formatTree;
|
|
132
137
|
exports.searchTreeById = tree.searchTreeById;
|
|
138
|
+
exports.weAppJwtDecode = weDecode.weAppJwtDecode;
|
|
139
|
+
exports.weAtob = weDecode.weAtob;
|
|
140
|
+
exports.weBtoa = weDecode.weBtoa;
|
package/lib/cjs/number.js
CHANGED
package/lib/cjs/object.js
CHANGED
package/lib/cjs/path.js
CHANGED
package/lib/cjs/qs.js
CHANGED
package/lib/cjs/random.js
CHANGED
package/lib/cjs/string.js
CHANGED
package/lib/cjs/tooltip.js
CHANGED
package/lib/cjs/tree.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.
|
|
3
|
-
* (c) 2023-
|
|
2
|
+
* sculp-js v1.3.0
|
|
3
|
+
* (c) 2023-2024 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
const defaultFieldOptions = { keyField: 'key', childField: 'children', pidField: 'pid' };
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* 深度优先遍历函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
|
|
12
12
|
* @param {ArrayLike<V>} tree 树形数据
|
|
13
13
|
* @param {Function} iterator 迭代函数, 返回值为true时continue, 返回值为false时break
|
|
14
14
|
* @param {string} children 定制子元素的key
|
|
@@ -63,6 +63,76 @@ function forEachDeep(tree, iterator, children = 'children', isReverse = false) {
|
|
|
63
63
|
};
|
|
64
64
|
walk(tree, null);
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* 深度优先遍历的Map函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
|
|
68
|
+
* @param {ArrayLike<V>} tree 树形数据
|
|
69
|
+
* @param {Function} iterator 迭代函数, 返回值为true时continue, 返回值为false时break
|
|
70
|
+
* @param {string} children 定制子元素的key
|
|
71
|
+
* @param {boolean} isReverse 是否反向遍历
|
|
72
|
+
* @returns {any[]} 新的一棵树
|
|
73
|
+
*/
|
|
74
|
+
function forEachMap(tree, iterator, children = 'children', isReverse = false) {
|
|
75
|
+
let level = 0, isBreak = false;
|
|
76
|
+
const newTree = [];
|
|
77
|
+
const walk = (arr, parent, newTree) => {
|
|
78
|
+
if (isReverse) {
|
|
79
|
+
for (let i = arr.length - 1; i >= 0; i--) {
|
|
80
|
+
if (isBreak) {
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
const re = iterator(arr[i], i, arr, tree, parent, level);
|
|
84
|
+
if (re === false) {
|
|
85
|
+
isBreak = true;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
else if (re === true) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
newTree.push(re);
|
|
92
|
+
// @ts-ignore
|
|
93
|
+
if (arr[i] && Array.isArray(arr[i][children])) {
|
|
94
|
+
++level;
|
|
95
|
+
newTree[newTree.length - 1][children] = [];
|
|
96
|
+
// @ts-ignore
|
|
97
|
+
walk(arr[i][children], arr[i], newTree[newTree.length - 1][children]);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// children非有效数组时,移除该属性字段
|
|
101
|
+
delete re[children];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
for (let i = 0; i < arr.length; i++) {
|
|
107
|
+
if (isBreak) {
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
const re = iterator(arr[i], i, arr, tree, parent, level);
|
|
111
|
+
if (re === false) {
|
|
112
|
+
isBreak = true;
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
else if (re === true) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
newTree.push(re);
|
|
119
|
+
// @ts-ignore
|
|
120
|
+
if (arr[i] && Array.isArray(arr[i][children])) {
|
|
121
|
+
++level;
|
|
122
|
+
newTree[newTree.length - 1][children] = [];
|
|
123
|
+
// @ts-ignore
|
|
124
|
+
walk(arr[i][children], arr[i], newTree[newTree.length - 1][children]);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// children非有效数组时,移除该属性字段
|
|
128
|
+
delete re[children];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
walk(tree, null, newTree);
|
|
134
|
+
return newTree;
|
|
135
|
+
}
|
|
66
136
|
/**
|
|
67
137
|
* 在树中找到 id 为某个值的节点,并返回上游的所有父级节点
|
|
68
138
|
*
|
|
@@ -208,5 +278,6 @@ function formatTree(list, options = defaultFieldOptions) {
|
|
|
208
278
|
|
|
209
279
|
exports.buildTree = buildTree;
|
|
210
280
|
exports.forEachDeep = forEachDeep;
|
|
281
|
+
exports.forEachMap = forEachMap;
|
|
211
282
|
exports.formatTree = formatTree;
|
|
212
283
|
exports.searchTreeById = searchTreeById;
|
package/lib/cjs/type.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* sculp-js v1.
|
|
3
|
-
* (c) 2023-
|
|
2
|
+
* sculp-js v1.3.0
|
|
3
|
+
* (c) 2023-2024 chandq
|
|
4
4
|
* Released under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -23,6 +23,9 @@ const isNumber = (any) => typeof any === 'number' && !Number.isNaN(any);
|
|
|
23
23
|
const isUndefined = (any) => typeof any === 'undefined';
|
|
24
24
|
const isNull = (any) => any === null;
|
|
25
25
|
const isPrimitive = (any) => any === null || typeof any !== 'object';
|
|
26
|
+
function isNullOrUnDef(val) {
|
|
27
|
+
return isUndefined(val) || isNull(val);
|
|
28
|
+
}
|
|
26
29
|
// 复合数据类型判断
|
|
27
30
|
const isObject = (any) => typeIs(any) === 'Object';
|
|
28
31
|
const isArray = (any) => Array.isArray(any);
|
|
@@ -47,6 +50,7 @@ exports.isError = isError;
|
|
|
47
50
|
exports.isFunction = isFunction;
|
|
48
51
|
exports.isNaN = isNaN;
|
|
49
52
|
exports.isNull = isNull;
|
|
53
|
+
exports.isNullOrUnDef = isNullOrUnDef;
|
|
50
54
|
exports.isNumber = isNumber;
|
|
51
55
|
exports.isObject = isObject;
|
|
52
56
|
exports.isPrimitive = isPrimitive;
|
package/lib/cjs/unique.js
CHANGED
package/lib/cjs/url.js
CHANGED
package/lib/cjs/watermark.js
CHANGED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* sculp-js v1.3.0
|
|
3
|
+
* (c) 2023-2024 chandq
|
|
4
|
+
* Released under the MIT License.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
10
|
+
// eslint-disable-next-line
|
|
11
|
+
const b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
|
|
12
|
+
/**
|
|
13
|
+
* 字符串编码成Base64 (适用于任何环境,包括小程序)
|
|
14
|
+
* @param {string} string
|
|
15
|
+
* @return {string}
|
|
16
|
+
*/
|
|
17
|
+
function weBtoa(string) {
|
|
18
|
+
// 同window.btoa: 字符串编码成Base64
|
|
19
|
+
string = String(string);
|
|
20
|
+
let bitmap, a, b, c, result = '', i = 0;
|
|
21
|
+
const rest = string.length % 3;
|
|
22
|
+
for (; i < string.length;) {
|
|
23
|
+
if ((a = string.charCodeAt(i++)) > 255 || (b = string.charCodeAt(i++)) > 255 || (c = string.charCodeAt(i++)) > 255)
|
|
24
|
+
throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.");
|
|
25
|
+
bitmap = (a << 16) | (b << 8) | c;
|
|
26
|
+
result +=
|
|
27
|
+
b64.charAt((bitmap >> 18) & 63) +
|
|
28
|
+
b64.charAt((bitmap >> 12) & 63) +
|
|
29
|
+
b64.charAt((bitmap >> 6) & 63) +
|
|
30
|
+
b64.charAt(bitmap & 63);
|
|
31
|
+
}
|
|
32
|
+
return rest ? result.slice(0, rest - 3) + '==='.substring(rest) : result;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Base64解码为原始字符串(适用于任何环境,包括小程序)
|
|
36
|
+
* @param {string} string
|
|
37
|
+
* @return {string}
|
|
38
|
+
*/
|
|
39
|
+
function weAtob(string) {
|
|
40
|
+
// 同window.atob: Base64解码为原始字符串
|
|
41
|
+
string = String(string).replace(/[\t\n\f\r ]+/g, '');
|
|
42
|
+
if (!b64re.test(string))
|
|
43
|
+
throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
|
|
44
|
+
string += '=='.slice(2 - (string.length & 3));
|
|
45
|
+
let bitmap, result = '', r1, r2, i = 0;
|
|
46
|
+
for (; i < string.length;) {
|
|
47
|
+
bitmap =
|
|
48
|
+
(b64.indexOf(string.charAt(i++)) << 18) |
|
|
49
|
+
(b64.indexOf(string.charAt(i++)) << 12) |
|
|
50
|
+
((r1 = b64.indexOf(string.charAt(i++))) << 6) |
|
|
51
|
+
(r2 = b64.indexOf(string.charAt(i++)));
|
|
52
|
+
result +=
|
|
53
|
+
r1 === 64
|
|
54
|
+
? String.fromCharCode((bitmap >> 16) & 255)
|
|
55
|
+
: r2 === 64
|
|
56
|
+
? String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255)
|
|
57
|
+
: String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255, bitmap & 255);
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
function b64DecodeUnicode(str) {
|
|
62
|
+
return decodeURIComponent(exports.weAtob(str).replace(/(.)/g, function (p) {
|
|
63
|
+
let code = p.charCodeAt(0).toString(16).toUpperCase();
|
|
64
|
+
if (code.length < 2) {
|
|
65
|
+
code = '0' + code;
|
|
66
|
+
}
|
|
67
|
+
return '%' + code;
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
function base64_url_decode(str) {
|
|
71
|
+
let output = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
72
|
+
switch (output.length % 4) {
|
|
73
|
+
case 0:
|
|
74
|
+
break;
|
|
75
|
+
case 2:
|
|
76
|
+
output += '==';
|
|
77
|
+
break;
|
|
78
|
+
case 3:
|
|
79
|
+
output += '=';
|
|
80
|
+
break;
|
|
81
|
+
default:
|
|
82
|
+
throw new Error('Illegal base64url string!');
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
return b64DecodeUnicode(output);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
return exports.weAtob(output);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function weAppJwtDecode(token, options) {
|
|
92
|
+
if (typeof token !== 'string') {
|
|
93
|
+
throw new Error('Invalid token specified');
|
|
94
|
+
}
|
|
95
|
+
options = options || {};
|
|
96
|
+
const pos = options.header === true ? 0 : 1;
|
|
97
|
+
try {
|
|
98
|
+
return JSON.parse(base64_url_decode(token.split('.')[pos]));
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
throw new Error('Invalid token specified: ' + e.message);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
exports.weAppJwtDecode = weAppJwtDecode;
|
|
106
|
+
exports.weAtob = weAtob;
|
|
107
|
+
exports.weBtoa = weBtoa;
|
package/lib/es/array.js
CHANGED
package/lib/es/async.js
CHANGED
package/lib/es/clipboard.js
CHANGED
package/lib/es/cookie.js
CHANGED