befly 0.1.26
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 +201 -0
- package/README.md +3 -0
- package/apis/health/info.js +33 -0
- package/checks/schema.js +132 -0
- package/config/env.js +56 -0
- package/libs/xml/DocTypeReader.js +362 -0
- package/libs/xml/OptionsBuilder.js +45 -0
- package/libs/xml/OrderedObjParser.js +597 -0
- package/libs/xml/XMLParser.js +69 -0
- package/libs/xml/ignoreAttributes.js +18 -0
- package/libs/xml/node2json.js +114 -0
- package/libs/xml/strnum.js +134 -0
- package/libs/xml/util.js +68 -0
- package/libs/xml/validator.js +425 -0
- package/libs/xml/xmlNode.js +40 -0
- package/main.js +410 -0
- package/package.json +53 -0
- package/plugins/cors.js +15 -0
- package/plugins/db.js +56 -0
- package/plugins/logger.js +13 -0
- package/plugins/redis.js +116 -0
- package/schema/common.json +17 -0
- package/schema/debug.json +1 -0
- package/schema/health.json +1 -0
- package/schema/tool.json +6 -0
- package/utils/api.js +49 -0
- package/utils/colors.js +83 -0
- package/utils/crypto.js +260 -0
- package/utils/curd.js +183 -0
- package/utils/jwt.js +154 -0
- package/utils/logger.js +143 -0
- package/utils/util.js +171 -0
- package/utils/validate.js +244 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import XmlNode from './xmlNode.js';
|
|
4
|
+
|
|
5
|
+
const METADATA_SYMBOL = XmlNode.getMetaDataSymbol();
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param {array} node
|
|
10
|
+
* @param {any} options
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
export default function prettify(node, options) {
|
|
14
|
+
return compress(node, options);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
*
|
|
19
|
+
* @param {array} arr
|
|
20
|
+
* @param {object} options
|
|
21
|
+
* @param {string} jPath
|
|
22
|
+
* @returns object
|
|
23
|
+
*/
|
|
24
|
+
function compress(arr, options, jPath) {
|
|
25
|
+
let text;
|
|
26
|
+
const compressedObj = {};
|
|
27
|
+
for (let i = 0; i < arr.length; i++) {
|
|
28
|
+
const tagObj = arr[i];
|
|
29
|
+
const property = propName(tagObj);
|
|
30
|
+
let newJpath = '';
|
|
31
|
+
if (jPath === undefined) newJpath = property;
|
|
32
|
+
else newJpath = jPath + '.' + property;
|
|
33
|
+
|
|
34
|
+
if (property === options.textNodeName) {
|
|
35
|
+
if (text === undefined) text = tagObj[property];
|
|
36
|
+
else text += '' + tagObj[property];
|
|
37
|
+
} else if (property === undefined) {
|
|
38
|
+
continue;
|
|
39
|
+
} else if (tagObj[property]) {
|
|
40
|
+
let val = compress(tagObj[property], options, newJpath);
|
|
41
|
+
const isLeaf = isLeafTag(val, options);
|
|
42
|
+
if (tagObj[METADATA_SYMBOL] !== undefined) {
|
|
43
|
+
val[METADATA_SYMBOL] = tagObj[METADATA_SYMBOL]; // copy over metadata
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (tagObj[':@']) {
|
|
47
|
+
assignAttributes(val, tagObj[':@'], newJpath, options);
|
|
48
|
+
} else if (Object.keys(val).length === 1 && val[options.textNodeName] !== undefined && !options.alwaysCreateTextNode) {
|
|
49
|
+
val = val[options.textNodeName];
|
|
50
|
+
} else if (Object.keys(val).length === 0) {
|
|
51
|
+
if (options.alwaysCreateTextNode) val[options.textNodeName] = '';
|
|
52
|
+
else val = '';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (compressedObj[property] !== undefined && compressedObj.hasOwnProperty(property)) {
|
|
56
|
+
if (!Array.isArray(compressedObj[property])) {
|
|
57
|
+
compressedObj[property] = [compressedObj[property]];
|
|
58
|
+
}
|
|
59
|
+
compressedObj[property].push(val);
|
|
60
|
+
} else {
|
|
61
|
+
//TODO: if a node is not an array, then check if it should be an array
|
|
62
|
+
//also determine if it is a leaf node
|
|
63
|
+
if (options.isArray(property, newJpath, isLeaf)) {
|
|
64
|
+
compressedObj[property] = [val];
|
|
65
|
+
} else {
|
|
66
|
+
compressedObj[property] = val;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// if(text && text.length > 0) compressedObj[options.textNodeName] = text;
|
|
72
|
+
if (typeof text === 'string') {
|
|
73
|
+
if (text.length > 0) compressedObj[options.textNodeName] = text;
|
|
74
|
+
} else if (text !== undefined) compressedObj[options.textNodeName] = text;
|
|
75
|
+
return compressedObj;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function propName(obj) {
|
|
79
|
+
const keys = Object.keys(obj);
|
|
80
|
+
for (let i = 0; i < keys.length; i++) {
|
|
81
|
+
const key = keys[i];
|
|
82
|
+
if (key !== ':@') return key;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function assignAttributes(obj, attrMap, jpath, options) {
|
|
87
|
+
if (attrMap) {
|
|
88
|
+
const keys = Object.keys(attrMap);
|
|
89
|
+
const len = keys.length; //don't make it inline
|
|
90
|
+
for (let i = 0; i < len; i++) {
|
|
91
|
+
const atrrName = keys[i];
|
|
92
|
+
if (options.isArray(atrrName, jpath + '.' + atrrName, true, true)) {
|
|
93
|
+
obj[atrrName] = [attrMap[atrrName]];
|
|
94
|
+
} else {
|
|
95
|
+
obj[atrrName] = attrMap[atrrName];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function isLeafTag(obj, options) {
|
|
102
|
+
const { textNodeName } = options;
|
|
103
|
+
const propCount = Object.keys(obj).length;
|
|
104
|
+
|
|
105
|
+
if (propCount === 0) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (propCount === 1 && (obj[textNodeName] || typeof obj[textNodeName] === 'boolean' || obj[textNodeName] === 0)) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;
|
|
2
|
+
const numRegex = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/;
|
|
3
|
+
// const octRegex = /^0x[a-z0-9]+/;
|
|
4
|
+
// const binRegex = /0x[a-z0-9]+/;
|
|
5
|
+
|
|
6
|
+
const consider = {
|
|
7
|
+
hex: true,
|
|
8
|
+
// oct: false,
|
|
9
|
+
leadingZeros: true,
|
|
10
|
+
decimalPoint: '.',
|
|
11
|
+
eNotation: true
|
|
12
|
+
//skipLike: /regex/
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default function toNumber(str, options = {}) {
|
|
16
|
+
options = Object.assign({}, consider, options);
|
|
17
|
+
if (!str || typeof str !== 'string') return str;
|
|
18
|
+
|
|
19
|
+
let trimmedStr = str.trim();
|
|
20
|
+
|
|
21
|
+
if (options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;
|
|
22
|
+
else if (str === '0') return 0;
|
|
23
|
+
else if (options.hex && hexRegex.test(trimmedStr)) {
|
|
24
|
+
return parse_int(trimmedStr, 16);
|
|
25
|
+
// }else if (options.oct && octRegex.test(str)) {
|
|
26
|
+
// return Number.parseInt(val, 8);
|
|
27
|
+
} else if (trimmedStr.search(/.+[eE].+/) !== -1) {
|
|
28
|
+
//eNotation
|
|
29
|
+
return resolveEnotation(str, trimmedStr, options);
|
|
30
|
+
// }else if (options.parseBin && binRegex.test(str)) {
|
|
31
|
+
// return Number.parseInt(val, 2);
|
|
32
|
+
} else {
|
|
33
|
+
//separate negative sign, leading zeros, and rest number
|
|
34
|
+
const match = numRegex.exec(trimmedStr);
|
|
35
|
+
// +00.123 => [ , '+', '00', '.123', ..
|
|
36
|
+
if (match) {
|
|
37
|
+
const sign = match[1] || '';
|
|
38
|
+
const leadingZeros = match[2];
|
|
39
|
+
let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros
|
|
40
|
+
const decimalAdjacentToLeadingZeros = sign // 0., -00., 000.
|
|
41
|
+
? str[leadingZeros.length + 1] === '.'
|
|
42
|
+
: str[leadingZeros.length] === '.';
|
|
43
|
+
|
|
44
|
+
//trim ending zeros for floating number
|
|
45
|
+
if (
|
|
46
|
+
!options.leadingZeros && //leading zeros are not allowed
|
|
47
|
+
(leadingZeros.length > 1 || (leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros))
|
|
48
|
+
) {
|
|
49
|
+
// 00, 00.3, +03.24, 03, 03.24
|
|
50
|
+
return str;
|
|
51
|
+
} else {
|
|
52
|
+
//no leading zeros or leading zeros are allowed
|
|
53
|
+
const num = Number(trimmedStr);
|
|
54
|
+
const parsedStr = String(num);
|
|
55
|
+
|
|
56
|
+
if (num === 0) return num;
|
|
57
|
+
if (parsedStr.search(/[eE]/) !== -1) {
|
|
58
|
+
//given number is long and parsed to eNotation
|
|
59
|
+
if (options.eNotation) return num;
|
|
60
|
+
else return str;
|
|
61
|
+
} else if (trimmedStr.indexOf('.') !== -1) {
|
|
62
|
+
//floating number
|
|
63
|
+
if (parsedStr === '0') return num; //0.0
|
|
64
|
+
else if (parsedStr === numTrimmedByZeros) return num; //0.456. 0.79000
|
|
65
|
+
else if (parsedStr === `${sign}${numTrimmedByZeros}`) return num;
|
|
66
|
+
else return str;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let n = leadingZeros ? numTrimmedByZeros : trimmedStr;
|
|
70
|
+
if (leadingZeros) {
|
|
71
|
+
// -009 => -9
|
|
72
|
+
return n === parsedStr || sign + n === parsedStr ? num : str;
|
|
73
|
+
} else {
|
|
74
|
+
// +9
|
|
75
|
+
return n === parsedStr || n === sign + parsedStr ? num : str;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
//non-numeric string
|
|
80
|
+
return str;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const eNotationRegx = /^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;
|
|
86
|
+
function resolveEnotation(str, trimmedStr, options) {
|
|
87
|
+
if (!options.eNotation) return str;
|
|
88
|
+
const notation = trimmedStr.match(eNotationRegx);
|
|
89
|
+
if (notation) {
|
|
90
|
+
let sign = notation[1] || '';
|
|
91
|
+
const eChar = notation[3].indexOf('e') === -1 ? 'E' : 'e';
|
|
92
|
+
const leadingZeros = notation[2];
|
|
93
|
+
const eAdjacentToLeadingZeros = sign // 0E.
|
|
94
|
+
? str[leadingZeros.length + 1] === eChar
|
|
95
|
+
: str[leadingZeros.length] === eChar;
|
|
96
|
+
|
|
97
|
+
if (leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;
|
|
98
|
+
else if (leadingZeros.length === 1 && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)) {
|
|
99
|
+
return Number(trimmedStr);
|
|
100
|
+
} else if (options.leadingZeros && !eAdjacentToLeadingZeros) {
|
|
101
|
+
//accept with leading zeros
|
|
102
|
+
//remove leading 0s
|
|
103
|
+
trimmedStr = (notation[1] || '') + notation[3];
|
|
104
|
+
return Number(trimmedStr);
|
|
105
|
+
} else return str;
|
|
106
|
+
} else {
|
|
107
|
+
return str;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
*
|
|
113
|
+
* @param {string} numStr without leading zeros
|
|
114
|
+
* @returns
|
|
115
|
+
*/
|
|
116
|
+
function trimZeros(numStr) {
|
|
117
|
+
if (numStr && numStr.indexOf('.') !== -1) {
|
|
118
|
+
//float
|
|
119
|
+
numStr = numStr.replace(/0+$/, ''); //remove ending zeros
|
|
120
|
+
if (numStr === '.') numStr = '0';
|
|
121
|
+
else if (numStr[0] === '.') numStr = '0' + numStr;
|
|
122
|
+
else if (numStr[numStr.length - 1] === '.') numStr = numStr.substring(0, numStr.length - 1);
|
|
123
|
+
return numStr;
|
|
124
|
+
}
|
|
125
|
+
return numStr;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function parse_int(numStr, base) {
|
|
129
|
+
//polyfill
|
|
130
|
+
if (parseInt) return parseInt(numStr, base);
|
|
131
|
+
else if (Number.parseInt) return Number.parseInt(numStr, base);
|
|
132
|
+
else if (window && window.parseInt) return window.parseInt(numStr, base);
|
|
133
|
+
else throw new Error('parseInt, Number.parseInt, window.parseInt are not supported');
|
|
134
|
+
}
|
package/libs/xml/util.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const nameStartChar = ':A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD';
|
|
4
|
+
const nameChar = nameStartChar + '\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040';
|
|
5
|
+
export const nameRegexp = '[' + nameStartChar + '][' + nameChar + ']*';
|
|
6
|
+
const regexName = new RegExp('^' + nameRegexp + '$');
|
|
7
|
+
|
|
8
|
+
export function getAllMatches(string, regex) {
|
|
9
|
+
const matches = [];
|
|
10
|
+
let match = regex.exec(string);
|
|
11
|
+
while (match) {
|
|
12
|
+
const allmatches = [];
|
|
13
|
+
allmatches.startIndex = regex.lastIndex - match[0].length;
|
|
14
|
+
const len = match.length;
|
|
15
|
+
for (let index = 0; index < len; index++) {
|
|
16
|
+
allmatches.push(match[index]);
|
|
17
|
+
}
|
|
18
|
+
matches.push(allmatches);
|
|
19
|
+
match = regex.exec(string);
|
|
20
|
+
}
|
|
21
|
+
return matches;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const isName = function(string) {
|
|
25
|
+
const match = regexName.exec(string);
|
|
26
|
+
return !(match === null || typeof match === 'undefined');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function isExist(v) {
|
|
30
|
+
return typeof v !== 'undefined';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function isEmptyObject(obj) {
|
|
34
|
+
return Object.keys(obj).length === 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Copy all the properties of a into b.
|
|
39
|
+
* @param {*} target
|
|
40
|
+
* @param {*} a
|
|
41
|
+
*/
|
|
42
|
+
export function merge(target, a, arrayMode) {
|
|
43
|
+
if (a) {
|
|
44
|
+
const keys = Object.keys(a); // will return an array of own properties
|
|
45
|
+
const len = keys.length; //don't make it inline
|
|
46
|
+
for (let i = 0; i < len; i++) {
|
|
47
|
+
if (arrayMode === 'strict') {
|
|
48
|
+
target[keys[i]] = [ a[keys[i]] ];
|
|
49
|
+
} else {
|
|
50
|
+
target[keys[i]] = a[keys[i]];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/* exports.merge =function (b,a){
|
|
56
|
+
return Object.assign(b,a);
|
|
57
|
+
} */
|
|
58
|
+
|
|
59
|
+
export function getValue(v) {
|
|
60
|
+
if (exports.isExist(v)) {
|
|
61
|
+
return v;
|
|
62
|
+
} else {
|
|
63
|
+
return '';
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// const fakeCall = function(a) {return a;};
|
|
68
|
+
// const fakeCallNoReturn = function() {};
|