refactor: 架构整固——分层单向化、全量 TypeScript、直接运行
- 移除 bd/mg 两平台及磁盘残留产物;清理 api-test 死脚本、musicSdk/message+options 死模块、infSign vendor - musicSdk/ 改名 sdk/;src/common、src/auth、src/apis 整体移入 sdk/,依赖方向定为 src → sdk 严格单向 - src/ 手写 JS 全量转 .ts,删除 JS 类型垫片 modules.d.ts;源码 import 统一 .ts 后缀 - Node 原生类型剥离直接运行 .ts(engines >=22.18),取消 tsc 发射产物,tsc 仅类型检查(pnpm typecheck) - 删除 kwdes 备用实现与 src/index.ts 转发垫片;测试移至 test/smoke-test.ts - common/request.ts 补显式导出类型;修复 set-cookie 单值形态、ApiError 类字段等隐患 验证:tsc 零错误,smoke-test 41/41
This commit is contained in:
1 parent
c8c939aa32
commit
354df2e739
126 files changed
+413
-2942
No files matched your search
@@ -0,0 +1,101 @@
|
||||
// 通用工具函数
|
||||
|
||||
import crypto from 'node:crypto'
|
||||
|
||||
/** MD5 十六进制串 */
|
||||
export const toMD5 = str => crypto.createHash('md5').update(str).digest('hex')
|
||||
|
||||
/**
|
||||
* 将大小格式化为可读字符串
|
||||
* @param {number} size 字节数
|
||||
*/
|
||||
export const sizeFormate = size => {
|
||||
// https://gist.github.com/thomseddon/3511330
|
||||
if (!size) return '0 B'
|
||||
const units = ['B', 'KB', 'MB', 'GB', 'TB']
|
||||
const number = Math.floor(Math.log(size) / Math.log(1024))
|
||||
return `${(size / Math.pow(1024, Math.floor(number))).toFixed(2)} ${units[number]}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 将秒数格式化为 mm:ss
|
||||
* @param {number} time 秒
|
||||
*/
|
||||
export const formatPlayTime = time => {
|
||||
if (Number.isNaN(time) || time < 0) time = 0
|
||||
const m = Math.trunc(time / 60)
|
||||
const s = Math.trunc(time % 60)
|
||||
return m == 0 && s == 0 ? '--/--' : `${m < 10 ? '0' + m : m}:${s < 10 ? '0' + s : s}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 将时间对象/时间戳转成日期字符串
|
||||
* @param {Date|number|string} _date 时间
|
||||
* @param {string} [format='Y-M-D h:m:s'] 格式模板(Y/M/D/h/m/s)
|
||||
*/
|
||||
export const dateFormat = (_date, format = 'Y-M-D h:m:s') => {
|
||||
if (!_date) return ''
|
||||
let date
|
||||
switch (typeof _date) {
|
||||
case 'string':
|
||||
if (!_date.includes('T')) _date = _date.split('.')[0].replace(/-/g, '/')
|
||||
// fallthrough
|
||||
case 'number':
|
||||
date = new Date(_date)
|
||||
break
|
||||
case 'object':
|
||||
date = _date
|
||||
break
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
const numFix = n => n < 10 ? '0' + n : String(n)
|
||||
return format
|
||||
.replace('Y', date.getFullYear().toString())
|
||||
.replace('M', numFix(date.getMonth() + 1))
|
||||
.replace('D', numFix(date.getDate()))
|
||||
.replace('h', numFix(date.getHours()))
|
||||
.replace('m', numFix(date.getMinutes()))
|
||||
.replace('s', numFix(date.getSeconds()))
|
||||
}
|
||||
|
||||
/**
|
||||
* 相对时间格式化(用于评论时间)
|
||||
* @param {number} time 毫秒时间戳
|
||||
*/
|
||||
export const dateFormat2 = time => {
|
||||
const differ = Math.trunc((Date.now() - time) / 1000)
|
||||
if (differ < 60) return `${differ}秒前`
|
||||
if (differ < 3600) return `${Math.trunc(differ / 60)}分钟前`
|
||||
if (differ < 86400) return `${Math.trunc(differ / 3600)}小时前`
|
||||
if (differ < 2592000) return `${Math.trunc(differ / 86400)}天前`
|
||||
return dateFormat(time)
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化播放量
|
||||
* @param {number} num
|
||||
*/
|
||||
export const formatPlayCount = num => {
|
||||
if (num > 100000000) return `${Math.trunc(num / 10000000) / 10}亿`
|
||||
if (num > 10000) return `${Math.trunc(num / 1000) / 10}万`
|
||||
return String(num)
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码 HTML 实体
|
||||
* @param {string} str
|
||||
*/
|
||||
export const decodeName = (str = '') => {
|
||||
if (!str) return ''
|
||||
if (typeof str !== 'string') str = String(str)
|
||||
return str
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, "'")
|
||||
.replace(/'/g, "'")
|
||||
.replace(/ /g, ' ')
|
||||
.replace(/&#(\d+);/g, (match, num) => String.fromCharCode(parseInt(num)))
|
||||
}
|
||||
Reference in new issue
Block a user