mirror of
https://github.com/NeteaseCloudMusicApiEnhanced/api-enhanced.git
synced 2026-10-20 22:51:23 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1bdc85998b | ||
|
|
49c7800afe | ||
|
|
19c7dad6db | ||
|
|
2db6684453 | ||
|
|
90de64140f |
@@ -14,15 +14,15 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
platform: linux
|
platform: linux
|
||||||
target: node18-linux-x64
|
target: node22-linux-x64
|
||||||
output: precompiled/app
|
output: precompiled/app
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
platform: win
|
platform: win
|
||||||
target: node18-win-x64
|
target: node22-win-x64
|
||||||
output: precompiled/app.exe
|
output: precompiled/app.exe
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
platform: macos
|
platform: macos
|
||||||
target: node18-macos-x64
|
target: node22-macos-x64
|
||||||
output: precompiled/app
|
output: precompiled/app
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -32,7 +32,7 @@ jobs:
|
|||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v6
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '24'
|
||||||
|
|
||||||
- name: Setup pnpm
|
- name: Setup pnpm
|
||||||
run: npm install -g pnpm@9
|
run: npm install -g pnpm@9
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node-version: [18, 22, 24]
|
node-version: [22, 24]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ jobs:
|
|||||||
github.actor != 'yukka-agent[bot]' &&
|
github.actor != 'yukka-agent[bot]' &&
|
||||||
github.actor != 'github-actions[bot]'
|
github.actor != 'github-actions[bot]'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 15
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
@@ -56,6 +57,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
OPENCODE_API_KEY: ${{ steps.cfg.outputs.opencode_api_key }}
|
OPENCODE_API_KEY: ${{ steps.cfg.outputs.opencode_api_key }}
|
||||||
GITHUB_TOKEN: ${{ steps.token.outputs.token }}
|
GITHUB_TOKEN: ${{ steps.token.outputs.token }}
|
||||||
|
OPENCODE_PERMISSION: '{"permission":{"*":"allow","question":"deny"}}'
|
||||||
with:
|
with:
|
||||||
model: opencode/muse-spark-1.3-contributor-free
|
model: opencode/muse-spark-1.3-contributor-free
|
||||||
use_github_token: true
|
use_github_token: true
|
||||||
|
|||||||
@@ -78,17 +78,17 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
platform: linux
|
platform: linux
|
||||||
target: node18-linux-x64
|
target: node22-linux-x64
|
||||||
output: ncm-api-linux-x64
|
output: ncm-api-linux-x64
|
||||||
|
|
||||||
- os: windows-latest
|
- os: windows-latest
|
||||||
platform: windows
|
platform: windows
|
||||||
target: node18-win-x64
|
target: node22-win-x64
|
||||||
output: ncm-api-win-x64.exe
|
output: ncm-api-win-x64.exe
|
||||||
|
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
platform: macos
|
platform: macos
|
||||||
target: node18-macos-x64
|
target: node22-macos-x64
|
||||||
output: ncm-api-macos-x64
|
output: ncm-api-macos-x64
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
## 快速开始
|
## 快速开始
|
||||||
- **包管理器**:开发与 CI 使用 `pnpm`,`Dockerfile` 也用 pnpm(`pnpm@9 --frozen-lockfile`,匹配 `pnpm-lock.yaml`)。仓库没有 `yarn.lock`,不要引入 yarn。
|
- **包管理器**:开发与 CI 使用 `pnpm`,`Dockerfile` 也用 pnpm(`pnpm@9 --frozen-lockfile`,匹配 `pnpm-lock.yaml`)。仓库没有 `yarn.lock`,不要引入 yarn。
|
||||||
- **Node 版本**:README 推荐 Node 22+;`package.json` 的 `engines` 声明 `>=12`;CI/打包在 Node 18–24 上运行。现代 Node 均可。
|
- **Node 版本**:`package.json` 的 `engines` 声明 `>=22`;CI/打包在 Node 22–24 上运行。现代 Node 均可。
|
||||||
- **环境变量**:`server.js` 调用了 `dotenv.config()`,本地 `.env` 会被自动加载;所有支持的变量见 `.env.prod.example`。
|
- **环境变量**:`server.js` 调用了 `dotenv.config()`,本地 `.env` 会被自动加载;所有支持的变量见 `.env.prod.example`。
|
||||||
|
|
||||||
## 常用命令
|
## 常用命令
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
- 跑测试:`pnpm test`(Mocha,超时 60s)
|
- 跑测试:`pnpm test`(Mocha,超时 60s)
|
||||||
- Lint:`pnpm lint`;自动修复:`pnpm lint-fix`
|
- Lint:`pnpm lint`;自动修复:`pnpm lint-fix`
|
||||||
- 文档格式化检查/修复:`pnpm docs:check` / `pnpm docs:format`
|
- 文档格式化检查/修复:`pnpm docs:check` / `pnpm docs:format`
|
||||||
- 打包独立二进制:`pnpm pkgwin` / `pkglinux` / `pkgmacos`
|
- 打包独立二进制:`pnpm pkgwin` / `pkglinux` / `pkgmacos`(@yao-pkg/pkg,node22 目标,`--no-bytecode` + `--public` 规避 node22 bytecode 回归)
|
||||||
|
|
||||||
## 目录内非路由文件
|
## 目录内非路由文件
|
||||||
- `plugins/`——内部上传辅助(`upload.js`、`songUpload.js`),被 `module/*` require,本身不是路由。
|
- `plugins/`——内部上传辅助(`upload.js`、`songUpload.js`),被 `module/*` require,本身不是路由。
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ docker run -d -p 3000:3000 moefurina/ncm-api:latest
|
|||||||
```bash
|
```bash
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
export PORT=9000
|
export PORT=9000
|
||||||
/var/lang/node16/bin/node app.js
|
/var/lang/node22/bin/node app.js
|
||||||
```
|
```
|
||||||
4. 完成部署后,访问 API 网关的 URL 即可
|
4. 完成部署后,访问 API 网关的 URL 即可
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,17 @@ const fs = require('fs')
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
const tmpPath = require('os').tmpdir()
|
const tmpPath = require('os').tmpdir()
|
||||||
|
|
||||||
|
// engines 字段只在 npm/pnpm 安装时生效,直接 node app.js 不会被拦截,
|
||||||
|
// 这里给出友好的最低版本检查(>=22,与 package.json engines 保持一致)
|
||||||
|
const [major] = process.versions.node.split('.').map(Number)
|
||||||
|
if (major < 22) {
|
||||||
|
console.error(
|
||||||
|
`[${new Date().toLocaleString()}] Node.js >= 22 is required (current: ${process.versions.node}). ` +
|
||||||
|
'请升级 Node.js 后重试 / Please upgrade Node.js to v22 or newer.',
|
||||||
|
)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
async function start() {
|
async function start() {
|
||||||
// 检测是否存在 anonymous_token 文件,没有则生成
|
// 检测是否存在 anonymous_token 文件,没有则生成
|
||||||
if (!fs.existsSync(path.resolve(tmpPath, 'anonymous_token'))) {
|
if (!fs.existsSync(path.resolve(tmpPath, 'anonymous_token'))) {
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// 每日风格推荐场景配置列表获取
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
const data = {}
|
||||||
|
return request(
|
||||||
|
`/api/homepage/daily/song/config/get`,
|
||||||
|
data,
|
||||||
|
createOption(query, 'xeapi'),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// 每日风格推荐场景配置设置
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
const data = {
|
||||||
|
tags: JSON.stringify({
|
||||||
|
tagIds: String(query.tags).split(',').map(Number),
|
||||||
|
categoryId: Number(query.category),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
console.log(data)
|
||||||
|
return request(
|
||||||
|
`/api/homepage/daily/song/tag/save`,
|
||||||
|
data,
|
||||||
|
createOption(query, 'xeapi'),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// 每日推荐风格歌曲
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
const data = {}
|
||||||
|
return request(
|
||||||
|
`/api/homepage/category/daily/song/list`,
|
||||||
|
data,
|
||||||
|
createOption(query, 'xeapi'),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// 每日推荐歌曲 - v1
|
||||||
|
|
||||||
|
const createOption = require('../util/option.js')
|
||||||
|
module.exports = (query, request) => {
|
||||||
|
const data = {
|
||||||
|
ispush: query.ispush || false,
|
||||||
|
}
|
||||||
|
return request(
|
||||||
|
`/api/v3/discovery/recommend/songs`,
|
||||||
|
data,
|
||||||
|
createOption(query, 'xeapi'),
|
||||||
|
)
|
||||||
|
}
|
||||||
+6
-6
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@neteasecloudmusicapienhanced/api",
|
"name": "@neteasecloudmusicapienhanced/api",
|
||||||
"version": "4.41.0",
|
"version": "5.0.0",
|
||||||
"description": "全网最全的网易云音乐API接口 || A revival project for NeteaseCloudMusicApi Node.js Services (Half Refactor & Enhanced)",
|
"description": "全网最全的网易云音乐API接口 || A revival project for NeteaseCloudMusicApi Node.js Services (Half Refactor & Enhanced)",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "nodemon app.js",
|
"dev": "nodemon app.js",
|
||||||
@@ -11,9 +11,9 @@
|
|||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
"docs:format": "node scripts/format-docs.js",
|
"docs:format": "node scripts/format-docs.js",
|
||||||
"docs:check": "node scripts/format-docs.js --check",
|
"docs:check": "node scripts/format-docs.js --check",
|
||||||
"pkgwin": "node scripts/build-pkg.js . -t node18-win-x64 -C GZip -o precompiled/app",
|
"pkgwin": "node scripts/build-pkg.js . -t node22-win-x64 -C GZip -o precompiled/app --no-bytecode --public-packages \"*\" --public",
|
||||||
"pkglinux": "node scripts/build-pkg.js . -t node18-linux-x64 -C GZip -o precompiled/app",
|
"pkglinux": "node scripts/build-pkg.js . -t node22-linux-x64 -C GZip -o precompiled/app --no-bytecode --public-packages \"*\" --public",
|
||||||
"pkgmacos": "node scripts/build-pkg.js . -t node18-macos-x64 -C GZip -o precompiled/app"
|
"pkgmacos": "node scripts/build-pkg.js . -t node22-macos-x64 -C GZip -o precompiled/app --no-bytecode --public-packages \"*\" --public"
|
||||||
},
|
},
|
||||||
"bin": "./app.js",
|
"bin": "./app.js",
|
||||||
"pkg": {
|
"pkg": {
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://neteasecloudmusicapienhanced.js.org/",
|
"homepage": "https://neteasecloudmusicapienhanced.js.org/",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=22"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.js": [
|
"*.js": [
|
||||||
@@ -112,7 +112,7 @@
|
|||||||
"lint-staged": "^16.4.0",
|
"lint-staged": "^16.4.0",
|
||||||
"mocha": "^11.8.0",
|
"mocha": "^11.8.0",
|
||||||
"nodemon": "^3.1.14",
|
"nodemon": "^3.1.14",
|
||||||
"pkg": "^5.8.1",
|
"@yao-pkg/pkg": "^6.23.0",
|
||||||
"power-assert": "^1.6.1",
|
"power-assert": "^1.6.1",
|
||||||
"prettier": "^3.9.9",
|
"prettier": "^3.9.9",
|
||||||
"typescript": "^5.9.3"
|
"typescript": "^5.9.3"
|
||||||
|
|||||||
Generated
+642
-262
File diff suppressed because it is too large
Load Diff
@@ -2391,6 +2391,16 @@ privilege:权限相关信息
|
|||||||
|
|
||||||
**调用例子 :** `/recommend/songs`
|
**调用例子 :** `/recommend/songs`
|
||||||
|
|
||||||
|
### 获取每日推荐歌曲 - v1
|
||||||
|
|
||||||
|
说明 : 调用此接口 , 可获得每日推荐歌曲 ( 需要登录 )
|
||||||
|
|
||||||
|
**可选参数 :** `ispush`: 是否刷新日推 , 默认为 false
|
||||||
|
|
||||||
|
**接口地址 :** `/recommend/songs/v1`
|
||||||
|
|
||||||
|
**调用例子 :** `/recommend/songs/v1`
|
||||||
|
|
||||||
### 每日推荐歌曲-不感兴趣
|
### 每日推荐歌曲-不感兴趣
|
||||||
|
|
||||||
说明 : 日推歌曲标记为不感兴趣( 同时会返回一个新推荐歌曲, 需要登录 )
|
说明 : 日推歌曲标记为不感兴趣( 同时会返回一个新推荐歌曲, 需要登录 )
|
||||||
@@ -5922,6 +5932,38 @@ let data = encodeURIComponent(
|
|||||||
|
|
||||||
**调用例子 :** `/fans/group/feed/recommend?fansGroupId=1872529203038486609&size=10&cursor=0`
|
**调用例子 :** `/fans/group/feed/recommend?fansGroupId=1872529203038486609&size=10&cursor=0`
|
||||||
|
|
||||||
|
### 每日指定风格歌曲推荐
|
||||||
|
|
||||||
|
说明 : 调用此接口 , 可获取每日指定风格歌曲推荐
|
||||||
|
|
||||||
|
**接口地址 :** `/recommend/category/songs`
|
||||||
|
|
||||||
|
**调用例子 :** `/recommend/category/songs`
|
||||||
|
|
||||||
|
### 获取每日指定风格歌曲推荐的风格列表
|
||||||
|
|
||||||
|
说明 : 调用此接口 , 可获取每日指定风格歌曲推荐的风格列表
|
||||||
|
|
||||||
|
**接口地址 :** `/recommend/category/configs`
|
||||||
|
|
||||||
|
**调用例子 :** `/recommend/category/configs`
|
||||||
|
|
||||||
|
### 设置每日指定风格歌曲推荐的风格
|
||||||
|
|
||||||
|
说明 : 调用此接口 , 可设置每日指定风格歌曲推荐的风格
|
||||||
|
|
||||||
|
**必选参数 :**
|
||||||
|
|
||||||
|
`tags`: 风格标签, 可通过 `/recommend/category/configs` 获取
|
||||||
|
|
||||||
|
`category`: 风格标签的父ID, 可通过 `/recommend/category/configs` 获取
|
||||||
|
|
||||||
|
!> 只能设置当前CategoryId下的tags, 不能设置其他CategoryId下的tags, 否则会报错
|
||||||
|
|
||||||
|
**接口地址 :** `/recommend/category/config`
|
||||||
|
|
||||||
|
**调用例子 :** `/recommend/category/config?tags=10004,10015&categoryId=1000`
|
||||||
|
|
||||||
## 离线访问此文档
|
## 离线访问此文档
|
||||||
|
|
||||||
此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问
|
此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问
|
||||||
|
|||||||
+16
-8
@@ -1,10 +1,10 @@
|
|||||||
/**
|
/**
|
||||||
* Invoke the pkg packager (cross-platform, independent of node_modules layout).
|
* Invoke the pkg packager (cross-platform, independent of node_modules layout).
|
||||||
*
|
*
|
||||||
* Background: on Windows, pnpm links node_modules/pkg to
|
* Background: on Windows, pnpm links node_modules/@yao-pkg/pkg to
|
||||||
* node_modules/.pnpm/pkg@<ver>/node_modules/pkg via a junction. Some CI
|
* node_modules/.pnpm/@yao-pkg+pkg@<ver>/node_modules/@yao-pkg/pkg via a junction.
|
||||||
* environments (pnpm 11 + Windows runner) may fail to create that link,
|
* Some CI environments (pnpm 11 + Windows runner) may fail to create that link,
|
||||||
* so executing node_modules/pkg/lib-es5/bin.js directly throws
|
* so executing node_modules/@yao-pkg/pkg/lib-es5/bin.js directly throws
|
||||||
* MODULE_NOT_FOUND.
|
* MODULE_NOT_FOUND.
|
||||||
*
|
*
|
||||||
* This script first resolves pkg via require.resolve and falls back to
|
* This script first resolves pkg via require.resolve and falls back to
|
||||||
@@ -17,16 +17,24 @@ const path = require('path')
|
|||||||
|
|
||||||
function resolvePkgBin() {
|
function resolvePkgBin() {
|
||||||
try {
|
try {
|
||||||
return require.resolve('pkg/lib-es5/bin.js')
|
return require.resolve('@yao-pkg/pkg/lib-es5/bin.js')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// require.resolve failed (e.g. missing node_modules/pkg link): scan .pnpm
|
// require.resolve failed (e.g. missing node_modules/@yao-pkg/pkg link): scan .pnpm
|
||||||
const pnpmDir = path.join(process.cwd(), 'node_modules', '.pnpm')
|
const pnpmDir = path.join(process.cwd(), 'node_modules', '.pnpm')
|
||||||
if (fs.existsSync(pnpmDir)) {
|
if (fs.existsSync(pnpmDir)) {
|
||||||
const candidates = fs
|
const candidates = fs
|
||||||
.readdirSync(pnpmDir)
|
.readdirSync(pnpmDir)
|
||||||
.filter((dir) => dir.startsWith('pkg@'))
|
.filter((dir) => dir.startsWith('@yao-pkg+pkg@'))
|
||||||
.map((dir) =>
|
.map((dir) =>
|
||||||
path.join(pnpmDir, dir, 'node_modules', 'pkg', 'lib-es5', 'bin.js'),
|
path.join(
|
||||||
|
pnpmDir,
|
||||||
|
dir,
|
||||||
|
'node_modules',
|
||||||
|
'@yao-pkg',
|
||||||
|
'pkg',
|
||||||
|
'lib-es5',
|
||||||
|
'bin.js',
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.filter((file) => fs.existsSync(file))
|
.filter((file) => fs.existsSync(file))
|
||||||
if (candidates.length) {
|
if (candidates.length) {
|
||||||
|
|||||||
Reference in New Issue
Block a user