|
| 1 | +// 封装对 @neteasecloudmusicapienhanced/api 内部模块的依赖 |
| 2 | +// 该包未对外导出 generateConfig / server 的稳定接口,此处集中处理「伸进内部文件」的耦合 |
| 3 | +import { existsSync } from "fs"; |
| 4 | +import { join } from "path"; |
| 5 | +import { tmpdir } from "os"; |
| 6 | +import { serverLog } from "../../main/logger"; |
| 7 | +import generateConfig from "@neteasecloudmusicapienhanced/api/generateConfig.js"; |
| 8 | +import ncmServerExports from "@neteasecloudmusicapienhanced/api/server.js"; |
| 9 | + |
| 10 | +// 包 server.js 的导出(serveNcmApi、getModulesDefinitions 等)会被合并到主入口对象上, |
| 11 | +// 它们不是网易云接口模块,必须从动态路由中排除,避免被当作 HTTP 接口调用(如 /netease/serve-ncm-api)。 |
| 12 | +export const NON_API_EXPORTS = new Set<string>([ |
| 13 | + ...Object.keys(ncmServerExports ?? {}), |
| 14 | + "server", // 主入口对象上的 server getter |
| 15 | +]); |
| 16 | + |
| 17 | +// xeapi 公钥缓存文件路径(由 generateConfig 写入系统临时目录) |
| 18 | +const xeapiPublicKeyPath = join(tmpdir(), "xeapi_public_key"); |
| 19 | + |
| 20 | +let ncmConfigReady = false; |
| 21 | +let ncmConfigPromise: Promise<void> | null = null; |
| 22 | + |
| 23 | +/** |
| 24 | + * 确保 NcmAPI 配置就绪 |
| 25 | + * |
| 26 | + * 新版本 @neteasecloudmusicapienhanced/api 的 song/url/v1 等接口改用 xeapi 加密, |
| 27 | + * 必须先调用 generateConfig 注册匿名 token 并获取 xeapi 公钥, |
| 28 | + * 否则请求会抛出 "xeapi public key is missing"。 |
| 29 | + * |
| 30 | + * 不阻塞服务启动;失败时不锁死状态,下次调用会自动重试。 |
| 31 | + */ |
| 32 | +export const ensureNcmConfig = (): Promise<void> => { |
| 33 | + if (ncmConfigReady) return Promise.resolve(); |
| 34 | + if (!ncmConfigPromise) { |
| 35 | + ncmConfigPromise = generateConfig() |
| 36 | + .then(() => { |
| 37 | + if (existsSync(xeapiPublicKeyPath)) { |
| 38 | + ncmConfigReady = true; |
| 39 | + serverLog.info("🔑 NcmAPI xeapi 公钥初始化完成"); |
| 40 | + } else { |
| 41 | + serverLog.error("❌ NcmAPI xeapi 公钥生成失败,下次请求将重试"); |
| 42 | + } |
| 43 | + }) |
| 44 | + .catch((error: unknown) => { |
| 45 | + serverLog.error("❌ NcmAPI 配置初始化失败:", error); |
| 46 | + }) |
| 47 | + .finally(() => { |
| 48 | + // 释放,未成功时允许后续请求重新尝试 |
| 49 | + ncmConfigPromise = null; |
| 50 | + }); |
| 51 | + } |
| 52 | + return ncmConfigPromise; |
| 53 | +}; |
0 commit comments