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,76 @@
|
||||
// 外部聚合音源统一入口(isolated-vm 懒加载封装)
|
||||
// 内部委托 source-ivm.ts 在硬隔离沙箱中执行音源脚本。
|
||||
// 首次调用 getMusicUrl 时才加载并初始化隔离环境,后续复用同一实例。
|
||||
// 统一接口约定:source.kw.getMusicUrl(songInfo, type) → { promise, cancelHttp },resolve → { type, url }
|
||||
//
|
||||
// 脚本来源(优先级):
|
||||
// 1. 环境变量 SOURCE_SCRIPT_PATH 指定的脚本文件
|
||||
// 2. sources/ 目录下按文件名排序的第一个 .js(脚本文件不入库,见 .gitignore)
|
||||
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { createIvmSource } from './source-ivm.ts'
|
||||
|
||||
export const SOURCES = ['kw', 'kg', 'tx', 'wy']
|
||||
|
||||
const SOURCES_DIR = fileURLToPath(new URL('../../sources/', import.meta.url))
|
||||
|
||||
const resolveScriptPath = () => {
|
||||
const custom = process.env.SOURCE_SCRIPT_PATH
|
||||
if (custom) return custom
|
||||
if (!fs.existsSync(SOURCES_DIR)) {
|
||||
throw new Error(`音源目录不存在: ${SOURCES_DIR}(将脚本放入 sources/ 目录,或用 SOURCE_SCRIPT_PATH 指定)`)
|
||||
}
|
||||
const files = fs.readdirSync(SOURCES_DIR).filter(f => f.toLowerCase().endsWith('.js')).sort()
|
||||
if (!files.length) {
|
||||
throw new Error('sources/ 目录下没有 .js 音源脚本(将脚本放入该目录,或用 SOURCE_SCRIPT_PATH 指定)')
|
||||
}
|
||||
if (files.length > 1) {
|
||||
console.log(`[source] sources/ 下有 ${files.length} 个脚本,使用 ${files[0]}(可用 SOURCE_SCRIPT_PATH 指定)`)
|
||||
}
|
||||
return path.join(SOURCES_DIR, files[0])
|
||||
}
|
||||
|
||||
let sharedPromise: Promise<any> | null = null
|
||||
|
||||
const getShared = () => {
|
||||
if (!sharedPromise) {
|
||||
// 配置可经环境变量调整,与项目其它适配器保持一致风格
|
||||
sharedPromise = createIvmSource({
|
||||
scriptPath: resolveScriptPath(),
|
||||
log: process.env.SOURCE_LOG !== '0',
|
||||
allowAllHttp: process.env.SOURCE_ALLOW_ALL_HTTP === '1',
|
||||
}).catch(err => {
|
||||
sharedPromise = null // 失败允许下次重试
|
||||
throw err
|
||||
})
|
||||
}
|
||||
return sharedPromise
|
||||
}
|
||||
|
||||
const apiFor = (source) => ({
|
||||
getMusicUrl(songInfo, type) {
|
||||
const requestObj = { cancelHttp() {}, promise: null as any }
|
||||
let inner: any = null
|
||||
requestObj.cancelHttp = () => inner?.cancelHttp()
|
||||
requestObj.promise = (async () => {
|
||||
const api = await getShared()
|
||||
if (!api[source]) throw new Error(`脚本不支持的平台: ${source}`)
|
||||
inner = api[source].getMusicUrl(songInfo, type)
|
||||
return inner.promise
|
||||
})()
|
||||
return requestObj
|
||||
},
|
||||
})
|
||||
|
||||
// 兼容导出:sdk/api-source.ts 以 createApi(source) 方式接入聚合音源
|
||||
export const createApi = apiFor
|
||||
|
||||
const sourceApi: Record<string, any> = {}
|
||||
for (const s of SOURCES) sourceApi[s] = apiFor(s)
|
||||
|
||||
// 预热:提前触发脚本加载与初始化(可选调用)
|
||||
sourceApi.init = getShared
|
||||
|
||||
export default sourceApi
|
||||
Reference in new issue
Block a user