rename index.js to coretool.js

This commit is contained in:
Luk Lu
2022-04-02 14:18:36 +08:00
parent 386ae27a1e
commit bff843fc4b
2 changed files with 1 additions and 0 deletions

193
index.js
View File

@@ -1,193 +0,0 @@
/* 基础小工具,可通用于服务端和用户端
*/
module.exports = {
sleep: (ms) => new Promise((resolve, reject) => setTimeout(resolve, ms)),
parseJsonPossible(value) {
try {
return JSON.parse(value)
} catch (e) {
return value
}
},
// 按顺序展开,哪怕嵌套。
stringifyOrdered (obj, {cmp, cycles = false, space = '', replacer, schemaColumns, excludeKeys = []} = {}) {
/* 这个解决方法不考虑缺省值,不能把嵌套对象也按顺序展开。*/
// return JSON.stringify(obj, Object.keys(schemaColumns || entity).sort().filter(key => ! excludeKeys.includes(key))) // JSON.stringify 可根据第二个数组参数的顺序排序
let newObj = {}
if (schemaColumns) {
for (let key in schemaColumns){
if (schemaColumns.hasOwnProperty(key) && ! schemaColumns[key].hashExclusive && ! excludeKeys.includes(key)) {
// JSON.stringify (包括本函数)会把 NaN 或 Infinity 输出为 null会把 undefined 忽略掉。
// 而在typeorm sqlite数据库中undefined 会自动存为 schemaColumns[key].default 或 null。从数据库读出时就会和事先JSON.stringify的结果不一致。
// 为了和数据库保持一致习惯对schemaColumns里的键值最好把 undefined 也设为 default 或 null。
if (obj[key] === undefined || Number.isNaN(obj[key]) || obj[key] === Infinity) {
newObj[key] = schemaColumns[key].default || null
obj[key] = schemaColumns[key].default || null // 确保内存中的数据和数据库保持一致
}else {
newObj[key] = obj[key]
}
}
}
}else{
newObj = obj
}
/* 以下代码来自 https://github.com/substack/json-stable-stringify 可把嵌套的复杂值也按顺序输出,例如 { c: 8, b: [{z:6,y:5,x:4},7], a: 3 } */
if (typeof space === 'number') space = Array(space+1).join(' ')
var cycles = (typeof cycles === 'boolean') ? cycles : false
var replacer = replacer || function(key, value) { return value }
var cmp = cmp && (function (f) {
return function (node) {
return function (a, b) {
var aobj = { key: a, value: node[a] }
var bobj = { key: b, value: node[b] }
return f(aobj, bobj)
}
}
})(cmp)
var seen = []
return (function stringify (parent, key, node, level) {
var indent = space ? ('\n' + new Array(level + 1).join(space)) : ''
var colonSeparator = space ? ': ' : ':'
if (node && node.toJSON && typeof node.toJSON === 'function') {
node = node.toJSON()
}
node = replacer.call(parent, key, node)
if (node === undefined) {
return
}
if (typeof node !== 'object' || node === null) {
return JSON.stringify(node)
}
if (Array.isArray(node)) {
var out = []
for (var i = 0; i < node.length; i++) {
var item = stringify(node, i, node[i], level+1) || JSON.stringify(null)
out.push(indent + space + item)
}
return '[' + out.join(',') + indent + ']'
}
else {
if (seen.indexOf(node) !== -1) {
if (cycles) return JSON.stringify('__cycle__')
throw new TypeError('Converting circular structure to JSON')
}
else seen.push(node)
var keys = Object.keys(node).sort(cmp && cmp(node))
var out = []
for (var i = 0; i < keys.length; i++) {
var key = keys[i]
var value = stringify(node, key, node[key], level+1)
if(!value) continue
var keyValue = JSON.stringify(key)
+ colonSeparator
+ value
out.push(indent + space + keyValue)
}
seen.splice(seen.indexOf(node), 1)
return '{' + out.join(',') + indent + '}'
}
})({ '': newObj }, '', newObj, 0)
},
name2port(name='') {
let port = name.toLowerCase()
.replace(/[abc]/g, 2)
.replace(/[def]/g, 3)
.replace(/[ghi]/g, 4)
.replace(/[jkl]/g, 5)
.replace(/[mno]/g, 6)
.replace(/[pqrs]/g, 7)
.replace(/[tuv]/g, 8)
.replace(/[wxyz]/g, 9)
return parseInt(port)
},
randomNumber ({ length, min, max } = {}) {
// 长度为 length 的随机数字,或者 (min||0) <= num < max
var num = 0
if (typeof length === 'number' && length > 0) {
num = parseInt(Math.random() * Math.pow(10, length))
num = num.toString().padStart(length, '0')
} else if (typeof max === 'number' && max > 0) {
min = typeof min === 'number' && min >= 0 ? min : 0
num = parseInt(Math.random() * (max - min)) + min
} else {
// 如果 option 为空
num = Math.random()
}
return num
},
hash (data, { hasher = 'sha256', salt, input = 'utf8', output = 'hex' } = {}) {
if (typeof data !== 'string' && !(data instanceof Buffer) && !(data instanceof DataView)) data = JSON.stringify(data)
if (salt && typeof salt === 'string') data = data + salt
const inputEncoding = input // my.INPUT_LIST.indexOf(option.input)>=0?option.input:my.INPUT // 'utf8', 'ascii' or 'latin1' for string data, default to utf8 if not specified; ignored for Buffer, TypedArray, or DataView.
const outputEncoding = output === 'buf' ? undefined : output // (my.OUTPUT_LIST.indexOf(output)>=0?output:my.OUTPUT) // option.output: 留空=》默认输出hex格式或者手动指定 'buf', hex', 'latin1' or 'base64'
return require('crypto').createHash(hasher).update(data, inputEncoding).digest(outputEncoding)
},
/**
* 用户编号转邀请码
*
* @static
* @param {*} aiid
* @return {*}
* @memberof TICrypto
*/
aiid2regcode (aiid) {
const alphabet = 'e5fcdg3hqa4b1n0pij2rstuv67mwx89klyz'
const base = 16367
let num = (aiid + base) * (base - alphabet.length)
let code = ''
let mod
while (num > 0) {
mod = num % alphabet.length
num = (num - mod) / alphabet.length
code = code + alphabet[mod] // 倒序存放
}
return code
},
/**
* 邀请码转用户编号
*
* @static
* @param {*} code
* @return {*}
* @memberof TICrypto
*/
regcode2aiid (code) {
if (typeof code === 'string' && /^[a-zA-Z0-9]+$/.test(code)) {
const alphabet = 'e5fcdg3hqa4b1n0pij2rstuv67mwx89klyz'
const base = 16367
code = code.toLowerCase()
let len = code.length
let num = 0
for (let i = 0; i < len; i++) {
num += alphabet.indexOf(code[i]) * Math.pow(alphabet.length, i)
}
let aiid = num / (base - alphabet.length) - base
if (aiid >= 0 && Number.isInteger(aiid)) {
// 允许 aiid===0当第一个用户aiid==1登录时需要一个系统默认的邀请码。
return aiid
}
}
return null // null 代表一切非法的regcode
},
}