Compare commits

..
7 Commits
16 changed files with 389 additions and 448 deletions
+20 -12
View File
@@ -1,8 +1,6 @@
name: OpenCode Automation
on:
issues:
types: [opened]
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
@@ -17,19 +15,25 @@ concurrency:
jobs:
automate:
# 排除机器人自己的触发,防止自我循环
# 排除其他机器人触发,防止自我循环;
# 但允许 takanashi-hoshino-agent 创建的 PR,这样 /oc 生成的测试 PR 也能被自动评审
if: |
github.actor != 'takanashi-hoshino-agent[bot]' &&
github.actor != 'github-actions[bot]' &&
github.actor != 'opencode-agent[bot]'
runs-on: ubuntu-latest
steps:
- name: Fetch config from CF Worker
id: cfg
uses: MoeFurina/pull-oc-config@v1
with:
url: https://bot-storage.interface.focalors.ltd/config
- name: Generate bot token
id: token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
app-id: ${{ steps.cfg.outputs.app_id }}
private-key: ${{ steps.cfg.outputs.app_private_key }}
owner: ${{ github.repository_owner }}
- name: Checkout
@@ -37,7 +41,7 @@ jobs:
with:
token: ${{ steps.token.outputs.token }}
fetch-depth: 0
persist-credentials: false
persist-credentials: true
- name: Setup Node.js
uses: actions/setup-node@v6
@@ -51,9 +55,13 @@ jobs:
env:
GITHUB_TOKEN: ${{ steps.token.outputs.token }}
MODEL: opencode/deepseek-v4-flash-free
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
ISSUE_PROMPT: ${{ secrets.OPENCODE_PROMPT }}
OPENCODE_API_KEY: ${{ steps.cfg.outputs.opencode_api_key }}
ISSUE_PROMPT: ${{ steps.cfg.outputs.opencode_prompt }}
PR_PROMPT: |
${{ secrets.OPENCODE_PROMPT }}
${{ secrets.PR_REVIEW_PROMPT }}
run: node scripts/opencode-automation.mjs
${{ steps.cfg.outputs.opencode_prompt }}
${{ steps.cfg.outputs.pr_review_prompt }}
run: |
mkdir -p scripts
curl -fsSL "https://raw.githubusercontent.com/MoeFurina/pull-oc-config/v1/scripts/opencode-automation.mjs" \
-o scripts/opencode-automation.mjs
node scripts/opencode-automation.mjs
+15 -5
View File
@@ -25,18 +25,25 @@ jobs:
permissions:
contents: read
steps:
- name: Fetch config from CF Worker
id: cfg
uses: MoeFurina/pull-oc-config@v1
with:
url: https://bot-storage.interface.focalors.ltd/config
- name: Generate bot token
id: token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
app-id: ${{ steps.cfg.outputs.app_id }}
private-key: ${{ steps.cfg.outputs.app_private_key }}
owner: ${{ github.repository_owner }}
- name: Checkout
uses: actions/checkout@v6
with:
persist-credentials: false
# 需要持久化凭证: opencode action 内部会 git fetch origin <分支> 拉取 PR 代码
persist-credentials: true
token: ${{ steps.token.outputs.token }}
- name: Configure git identity
@@ -47,10 +54,13 @@ jobs:
- name: Run opencode
uses: anomalyco/opencode/github@latest
env:
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
OPENCODE_API_KEY: ${{ steps.cfg.outputs.opencode_api_key }}
GITHUB_TOKEN: ${{ steps.token.outputs.token }}
with:
model: opencode/deepseek-v4-flash-free
use_github_token: true
prompt: |
${{ secrets.OPENCODE_PROMPT }}
${{ steps.cfg.outputs.opencode_prompt }}
## 用户指令(来自触发评论,请严格按此执行)
${{ github.event.comment.body }}
+4 -2
View File
@@ -2,7 +2,7 @@ FROM node:lts-alpine
RUN apk add --no-cache tini
ENV NODE_ENV production
ENV NODE_ENV=production
RUN npm install -g pnpm@9
@@ -12,7 +12,9 @@ WORKDIR /app
COPY --chown=node:node . ./
RUN pnpm install --frozen-lockfile --prod
# --prod 模式下 husky 不会被安装,prepare 脚本会因找不到 husky 而失败,
# 故显式跳过生命周期脚本;本项目生产运行也不依赖任何 postinstall 步骤。
RUN pnpm install --frozen-lockfile --prod --ignore-scripts
EXPOSE 3000
+1
View File
@@ -1378,6 +1378,7 @@ export const enum SoundQualityType {
jyeffect = 'jyeffect',
jymaster = 'jymaster',
sky = 'sky',
vivid = 'vivid',
}
export function song_url_v1(
+13
View File
@@ -0,0 +1,13 @@
// 红心与取消红心歌曲- v1
const createOption = require('../util/option.js')
module.exports = (query, request) => {
query.like = query.like == 'false' ? false : true
const data = {
alg: 'itembased',
trackId: query.id,
like: query.like,
time: '3',
}
return request(`/api/v1/radio/like`, data, createOption(query, 'xeapi', 'v3'))
}
-3
View File
@@ -1,8 +1,5 @@
// 私人FM - 模式选择
// aidj, DEFAULT, FAMILIAR, EXPLORE, SCENE_RCMD ( EXERCISE, FOCUS, NIGHT_EMO )
// 来不及解释这几个了
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
+12 -2
View File
@@ -1,13 +1,23 @@
// 获取客户端歌曲下载链接 - v1
// 此版本不再采用 br 作为音质区分的标准
// 而是采用 standard, exhigh, lossless, hires, jyeffect(高清环绕声), sky(沉浸环绕声), jymaster(超清母带) 进行音质判断
// 而是采用 standard, exhigh, lossless, hires, jyeffect(高清环绕声), sky(沉浸环绕声), vivid(臻音全景声), jymaster(超清母带) 进行音质判断
const createOption = require('../util/option.js')
const { cookieToJson } = require('../util/index.js')
module.exports = (query, request) => {
const data = {
id: query.id,
immerseType: 'c51',
level: query.level,
}
return request(`/api/song/enhance/download/url/v1`, data, createOption(query))
const options = createOption(query)
if (query.level === 'vivid') {
const cookie = options.cookie
options.cookie = {
...(typeof cookie === 'string' ? cookieToJson(cookie) : cookie),
os: 'android',
appver: '9.5.61',
}
}
return request(`/api/song/enhance/download/url/v1`, data, options)
}
+15
View File
@@ -0,0 +1,15 @@
// 插播相似歌曲
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const data = {
positionCode: 'toolBarRcmdSong',
resourceId: query.id,
resourceType: 'song',
}
return request(
`/api/link/position/show/resource`,
data,
createOption(query, 'eapi'),
)
}
+13 -6
View File
@@ -1,11 +1,12 @@
// 歌曲链接 - v1
// 此版本不再采用 br 作为音质区分的标准
// 而是采用 standard, exhigh, lossless, hires, jyeffect(高清环绕声), sky(沉浸环绕声), jymaster(超清母带) 进行音质判断
// 而是采用 standard, exhigh, lossless, hires, jyeffect(高清环绕声), sky(沉浸环绕声), vivid(臻音全景声), jymaster(超清母带) 进行音质判断
// 当unblock为true时, 会尝试使用unblockmusic-utils进行解锁, 同时音质设置不会生效, 但仍然为必须传入参数
// 当level为sky时, 可通过 immerseType 选择沉浸声类型, 支持 c51(c51类型)、ste(环绕立体声类型)、aac(aac类型), 默认为 c51
const logger = require('../util/logger.js')
const createOption = require('../util/option.js')
const { cookieToJson } = require('../util/index.js')
module.exports = async (query, request) => {
const {
matchID,
@@ -16,6 +17,7 @@ module.exports = async (query, request) => {
level: query.level,
encodeType: 'flac',
}
const options = createOption(query, 'xeapi')
if (query.unblock === 'true') {
try {
const result = await matchID(query.id, query.source)
@@ -54,9 +56,14 @@ module.exports = async (query, request) => {
if (data.level == 'sky') {
data.immerseType = query.immerseType || 'c51'
}
return request(
`/api/song/enhance/player/url/v1`,
data,
createOption(query, 'xeapi'),
)
if (data.level == 'vivid') {
data.encodeType = 'mp3'
const cookie = options.cookie
options.cookie = {
...(typeof cookie === 'string' ? cookieToJson(cookie) : cookie),
os: 'android',
appver: '9.5.61',
}
}
return request(`/api/song/enhance/player/url/v1`, data, options)
}
+17 -4
View File
@@ -1,20 +1,30 @@
// 获取客户端歌曲下载链接 - v1
// 此版本不再采用 br 作为音质区分的标准
// 而是采用 standard, exhigh, lossless, hires, jyeffect(高清环绕声), sky(沉浸环绕声), jymaster(超清母带) 进行音质判断
// 而是采用 standard, exhigh, lossless, hires, jyeffect(高清环绕声), sky(沉浸环绕声), vivid(臻音全景声), jymaster(超清母带) 进行音质判断
const createOption = require('../util/option.js')
const { cookieToJson } = require('../util/index.js')
module.exports = async (query, request) => {
const data = {
id: query.id,
immerseType: 'c51',
level: query.level,
}
const options = createOption(query)
if (query.level === 'vivid') {
const cookie = options.cookie
options.cookie = {
...(typeof cookie === 'string' ? cookieToJson(cookie) : cookie),
os: 'android',
appver: '9.5.61',
}
}
const response = await request(
`/api/song/enhance/download/url/v1`,
data,
createOption(query),
options,
)
let url = response?.body?.data?.[0]?.url
let url = response?.body?.data?.url || response?.body?.data?.[0]?.url
if (!url) {
const fallbackData = {
@@ -25,10 +35,13 @@ module.exports = async (query, request) => {
if (query.level === 'sky') {
fallbackData.immerseType = 'c51'
}
if (query.level === 'vivid') {
fallbackData.encodeType = 'mp3'
}
const fallback = await request(
`/api/song/enhance/player/url/v1`,
fallbackData,
createOption(query),
options,
)
url = fallback?.body?.data?.[0]?.url
+22
View File
@@ -0,0 +1,22 @@
// 歌曲百科
const createOption = require('../util/option.js')
module.exports = (query, request) => {
const extJson = {
states: {
playingResource: {
current: query.id,
scene: 'songWiki',
},
},
}
const data = {
extJson: JSON.stringify(extJson),
positionCode: 'songWikiMainPosition',
}
return request(
`/api/link/page/parent/relation/construct/info`,
data,
createOption(query, 'eapi'),
)
}
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@neteasecloudmusicapienhanced/api",
"version": "4.40.0",
"version": "4.40.1",
"description": "全网最全的网易云音乐API接口 || A revival project for NeteaseCloudMusicApi Node.js Services (Half Refactor & Enhanced) || 网易云音乐 API 备份 + 增强 || 本项目自原版v4.28.0版本后开始自行维护",
"scripts": {
"dev": "nodemon app.js",
@@ -75,7 +75,7 @@
"data"
],
"dependencies": {
"@neteasecloudmusicapienhanced/unblockmusic-utils": "^0.4.0",
"@neteasecloudmusicapienhanced/unblockmusic-utils": "^0.4.2",
"axios": "^1.19.0",
"crypto-js": "^4.2.0",
"dotenv": "^17.4.2",
@@ -99,13 +99,13 @@
"@types/express-fileupload": "^1.5.1",
"@types/mocha": "^10.0.10",
"@types/node": "25.9.2",
"@typescript-eslint/eslint-plugin": "^8.66.0",
"@typescript-eslint/parser": "^8.66.0",
"@typescript-eslint/eslint-plugin": "^8.67.0",
"@typescript-eslint/parser": "^8.67.0",
"eslint": "^9.39.5",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-html": "^8.1.4",
"eslint-plugin-prettier": "^5.5.6",
"globals": "^17.9.0",
"globals": "^17.11.0",
"husky": "^9.1.7",
"intelli-espower-loader": "^1.1.0",
"lint-staged": "^16.4.0",
+209 -199
View File
@@ -9,11 +9,11 @@ importers:
.:
dependencies:
'@neteasecloudmusicapienhanced/unblockmusic-utils':
specifier: ^0.4.0
version: 0.4.0
specifier: ^0.4.2
version: 0.4.2(debug@4.4.3(supports-color@5.5.0))(supports-color@5.5.0)
axios:
specifier: ^1.19.0
version: 1.19.0
version: 1.19.0(debug@4.4.3(supports-color@5.5.0))(supports-color@5.5.0)
crypto-js:
specifier: ^4.2.0
version: 4.2.0
@@ -22,7 +22,7 @@ importers:
version: 17.4.2
express:
specifier: ^5.2.1
version: 5.2.1
version: 5.2.1(supports-color@5.5.0)
express-fileupload:
specifier: ^1.5.2
version: 1.5.2
@@ -31,16 +31,16 @@ importers:
version: 0.1.0
jsdom:
specifier: ^24.1.3
version: 24.1.3
version: 24.1.3(supports-color@5.5.0)
music-metadata:
specifier: ^11.14.0
version: 11.14.0
version: 11.14.0(supports-color@5.5.0)
node-forge:
specifier: ^1.4.0
version: 1.4.0
pac-proxy-agent:
specifier: ^7.2.0
version: 7.2.0
version: 7.2.0(supports-color@5.5.0)
qrcode:
specifier: ^1.5.4
version: 1.5.4
@@ -59,7 +59,7 @@ importers:
devDependencies:
'@eslint/eslintrc':
specifier: ^3.3.6
version: 3.3.6
version: 3.3.6(supports-color@5.5.0)
'@eslint/js':
specifier: ^9.39.5
version: 9.39.5
@@ -76,26 +76,26 @@ importers:
specifier: 25.9.2
version: 25.9.2
'@typescript-eslint/eslint-plugin':
specifier: ^8.66.0
version: 8.66.0(@typescript-eslint/parser@8.66.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5)(typescript@5.9.3)
specifier: ^8.67.0
version: 8.67.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(supports-color@5.5.0))(supports-color@5.5.0)(typescript@5.9.3))(eslint@9.39.5(supports-color@5.5.0))(supports-color@5.5.0)(typescript@5.9.3)
'@typescript-eslint/parser':
specifier: ^8.66.0
version: 8.66.0(eslint@9.39.5)(typescript@5.9.3)
specifier: ^8.67.0
version: 8.67.0(eslint@9.39.5(supports-color@5.5.0))(supports-color@5.5.0)(typescript@5.9.3)
eslint:
specifier: ^9.39.5
version: 9.39.5
version: 9.39.5(supports-color@5.5.0)
eslint-config-prettier:
specifier: ^10.1.8
version: 10.1.8(eslint@9.39.5)
version: 10.1.8(eslint@9.39.5(supports-color@5.5.0))
eslint-plugin-html:
specifier: ^8.1.4
version: 8.1.4
eslint-plugin-prettier:
specifier: ^5.5.6
version: 5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5))(eslint@9.39.5)(prettier@3.9.6)
version: 5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5(supports-color@5.5.0)))(eslint@9.39.5(supports-color@5.5.0))(prettier@3.9.6)
globals:
specifier: ^17.9.0
version: 17.9.0
specifier: ^17.11.0
version: 17.11.0
husky:
specifier: ^9.1.7
version: 9.1.7
@@ -113,7 +113,7 @@ importers:
version: 3.1.14
pkg:
specifier: ^5.8.1
version: 5.8.1
version: 5.8.1(supports-color@5.5.0)
power-assert:
specifier: ^1.6.1
version: 1.6.1
@@ -150,6 +150,10 @@ packages:
resolution: {integrity: sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==}
engines: {node: '>=6.9.0'}
'@babel/types@7.29.8':
resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==}
engines: {node: '>=6.9.0'}
'@borewit/text-codec@0.2.2':
resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==}
@@ -256,8 +260,8 @@ packages:
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
'@neteasecloudmusicapienhanced/unblockmusic-utils@0.4.0':
resolution: {integrity: sha512-KUDdBEe3IK4tPSt2UHdFweYbhoZUYGBxbt8FuqQu5bZdpymfpecZxLf+a8G/JvIYHph4H+KxYlq6+MD9oXCfjg==}
'@neteasecloudmusicapienhanced/unblockmusic-utils@0.4.2':
resolution: {integrity: sha512-voVIb3Yn2gy093L8FEFo3B//iYKEUd5NB8ItzQrZUCDYs1YWIrf1y+WPlQg8LL78TojkLH8aBKuGn9wUWntnCQ==}
hasBin: true
'@nodelib/fs.scandir@2.1.5':
@@ -335,63 +339,63 @@ packages:
'@types/serve-static@2.2.0':
resolution: {integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==}
'@typescript-eslint/eslint-plugin@8.66.0':
resolution: {integrity: sha512-p088eaGrzYz1s+7cov0aMOCkNGTJlVxF4jgubf28c8L0Cv9Rloj8YBHnv4hXLq6IIEE1AsjNWavO+k+8kP2Y0A==}
'@typescript-eslint/eslint-plugin@8.67.0':
resolution: {integrity: sha512-Un7Heoyj65NREbKAyIrFxeM143NZpExWmy1Nep4DLeQOeLlTeumPjoNKnBrU5D5moWXbPJgRa5Uwcdu0faVNGQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
'@typescript-eslint/parser': ^8.66.0
'@typescript-eslint/parser': ^8.67.0
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.1.0'
'@typescript-eslint/parser@8.66.0':
resolution: {integrity: sha512-X6ypGChaWYk6PBtUg2BwuTZEFFcHJAtGTVJ9/lCTOufhZ4i9fNolQNnktq+kkMCwMj7V8Svsq7+TxSDslmhE0g==}
'@typescript-eslint/parser@8.67.0':
resolution: {integrity: sha512-fUBfTuuEulWqX6V8+O3PtScV01tzYYRUDTAirHFKoRAt7nOzoGiPt0M/bB47wWNy0coOOcgEwAMUtBpykMxl6w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.1.0'
'@typescript-eslint/project-service@8.66.0':
resolution: {integrity: sha512-7MthGPTt4BP69lSryqpqq8HQqxuzynssckL/jyDyk3+TNMQ3y2jFWkptCrktWvBrP+EH787Nl5N5Qpw7WZg+5g==}
'@typescript-eslint/project-service@8.67.0':
resolution: {integrity: sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.1.0'
'@typescript-eslint/scope-manager@8.66.0':
resolution: {integrity: sha512-8TGcH25j9zqJ/IULB/ppyhRvxA8QYfFEZ7nfbg6/BN9spDgb8fPWQXlE5l8TWBL50EtUx007uZ1o9VOwrq2/9g==}
'@typescript-eslint/scope-manager@8.67.0':
resolution: {integrity: sha512-EgvsleTwS4E+WzzSvem8fAUubLwatMNF1B5hHSLQxcvs7q2dtRhGyujHwLJSYlG41niJ7GP24Aha2+0mb1b2kg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/tsconfig-utils@8.66.0':
resolution: {integrity: sha512-9D5gLYZG4rOjcoag8MQ/fWI8WqA9wcPDyOGyWtWFhvM1lHRbliqUSPIY5J3zqCU1tvSwzXxnnjhQhz5Ne7mJ4g==}
'@typescript-eslint/tsconfig-utils@8.67.0':
resolution: {integrity: sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.1.0'
'@typescript-eslint/type-utils@8.66.0':
resolution: {integrity: sha512-LG2dWfjZQQp0ADtAu/EWJVayefGL2UEZ3CDeI44D9v3rXB/WYUqE/jpO28KrEKul5AySrmI+Zh1v6v+xW2U9+g==}
'@typescript-eslint/type-utils@8.67.0':
resolution: {integrity: sha512-aVWDXbRmdXO9siTfX4ditQI1T9+zVcNazT48EJCD0v40/9RIFoUgZ05CmGEq9H2gixRpjUn/iplwvlcvutJW/Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.1.0'
'@typescript-eslint/types@8.66.0':
resolution: {integrity: sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ==}
'@typescript-eslint/types@8.67.0':
resolution: {integrity: sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/typescript-estree@8.66.0':
resolution: {integrity: sha512-8/x4INiiQb10jGgXYD7116/zQ+OL84ZIFn0za68wwFHCanT/VLbBEroWht8RV8fn0/ZCAoazHLQgwUC0UQcDfg==}
'@typescript-eslint/typescript-estree@8.67.0':
resolution: {integrity: sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.1.0'
'@typescript-eslint/utils@8.66.0':
resolution: {integrity: sha512-jasearZPolBw5NJNYGMwxzHMF83niVWmMU1VdHzG1CyfI2VS7f7nZltnKtHcg20hW+7Uo5GfK4MeDPoU3qI8EA==}
'@typescript-eslint/utils@8.67.0':
resolution: {integrity: sha512-U9D1FdwEWBwok3hxxSdhclMb0twvt9QnjIQ0VfQ1AiX2epnpSgv2ubVDsayOFyY8K6FX+AQ7E0FKWVG3iKsj1A==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.1.0'
'@typescript-eslint/visitor-keys@8.66.0':
resolution: {integrity: sha512-dkKR8q+lKciskj1Y3vthHktl+3cMLWGyVUP23bRiPZ5O9BRT++4EqDDV+TVeIKBL1VXVEqrJlz8MYbcnvJcAlg==}
'@typescript-eslint/visitor-keys@8.67.0':
resolution: {integrity: sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@unblockneteasemusic/server@0.28.0':
@@ -448,8 +452,8 @@ packages:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
ansi-regex@6.2.2:
resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==}
ansi-regex@6.3.0:
resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==}
engines: {node: '>=12'}
ansi-styles@3.2.1:
@@ -694,8 +698,8 @@ packages:
resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
engines: {node: '>= 0.6'}
content-type@2.0.0:
resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==}
content-type@2.1.0:
resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==}
engines: {node: '>=18'}
convert-source-map@1.9.0:
@@ -725,6 +729,7 @@ packages:
crypto-js@4.2.0:
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
deprecated: Active development of CryptoJS has been discontinued. This library is no longer maintained.
cssstyle@4.6.0:
resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==}
@@ -1311,8 +1316,8 @@ packages:
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
engines: {node: '>=18'}
globals@17.9.0:
resolution: {integrity: sha512-m/MvAW61QVU5VDNF1Vj8axt016h8w7L5TU1e9zlab7XIttAT2YAlCwl75K1fOqvMM9apmD7lbCIRhpfkhmxhCg==}
globals@17.11.0:
resolution: {integrity: sha512-Z2I8hM+PbJDXQDq3Icgpzv+mPdwr68iZUU9d5WW4FuXfDUQfkZaZuvjMv42/5crNyw154+9+VWXbYrUgDXbxNw==}
engines: {node: '>=18'}
globalthis@1.0.4:
@@ -1457,8 +1462,8 @@ packages:
resolution: {integrity: sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==}
engines: {node: '>=10'}
ip-address@10.4.0:
resolution: {integrity: sha512-oSK96Grm3aP6OrS263xVxbNDGVL7rzBtYdpGqlDG8iQdoenDoTs/nkki+DflYbAEE8Xl6o5YxhxlrKvI3nqKXQ==}
ip-address@10.5.0:
resolution: {integrity: sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g==}
engines: {node: '>= 12'}
ipaddr.js@1.9.1:
@@ -2729,8 +2734,8 @@ packages:
wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
ws@8.21.2:
resolution: {integrity: sha512-54dMVAo4WIe6SKy3vBgN+9bJZqqQ8IMRevAkOLQALhi49qkkQDQfWdAZ8KQlXiEabw88ARXXdUrlvtbKQX+aKw==}
ws@8.21.3:
resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
@@ -2827,7 +2832,7 @@ snapshots:
'@babel/generator@7.18.2':
dependencies:
'@babel/types': 7.19.0
'@babel/types': 7.29.8
'@jridgewell/gen-mapping': 0.3.13
jsesc: 2.5.2
@@ -2837,7 +2842,7 @@ snapshots:
'@babel/parser@7.18.4':
dependencies:
'@babel/types': 7.19.0
'@babel/types': 7.29.8
'@babel/types@7.19.0':
dependencies:
@@ -2845,6 +2850,11 @@ snapshots:
'@babel/helper-validator-identifier': 7.29.7
to-fast-properties: 2.0.0
'@babel/types@7.29.8':
dependencies:
'@babel/helper-string-parser': 7.29.7
'@babel/helper-validator-identifier': 7.29.7
'@borewit/text-codec@0.2.2': {}
'@csstools/color-helpers@5.1.0': {}
@@ -2867,17 +2877,17 @@ snapshots:
'@csstools/css-tokenizer@3.0.4': {}
'@eslint-community/eslint-utils@4.10.1(eslint@9.39.5)':
'@eslint-community/eslint-utils@4.10.1(eslint@9.39.5(supports-color@5.5.0))':
dependencies:
eslint: 9.39.5
eslint: 9.39.5(supports-color@5.5.0)
eslint-visitor-keys: 3.4.3
'@eslint-community/regexpp@4.12.2': {}
'@eslint/config-array@0.21.2':
'@eslint/config-array@0.21.2(supports-color@5.5.0)':
dependencies:
'@eslint/object-schema': 2.1.7
debug: 4.4.3
debug: 4.4.3(supports-color@5.5.0)
minimatch: 3.1.5
transitivePeerDependencies:
- supports-color
@@ -2890,10 +2900,10 @@ snapshots:
dependencies:
'@types/json-schema': 7.0.15
'@eslint/eslintrc@3.3.6':
'@eslint/eslintrc@3.3.6(supports-color@5.5.0)':
dependencies:
ajv: 6.15.0
debug: 4.4.3
debug: 4.4.3(supports-color@5.5.0)
espree: 10.4.0
globals: 14.0.0
ignore: 5.3.2
@@ -2952,12 +2962,12 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
'@neteasecloudmusicapienhanced/unblockmusic-utils@0.4.0':
'@neteasecloudmusicapienhanced/unblockmusic-utils@0.4.2(debug@4.4.3(supports-color@5.5.0))(supports-color@5.5.0)':
dependencies:
'@unblockneteasemusic/server': 0.28.0
axios: 1.19.0
axios: 1.19.0(debug@4.4.3(supports-color@5.5.0))(supports-color@5.5.0)
dotenv: 17.4.2
express: 4.22.2
express: 4.22.2(supports-color@5.5.0)
https: 1.0.0
transitivePeerDependencies:
- debug
@@ -2980,9 +2990,9 @@ snapshots:
'@pkgr/core@0.3.6': {}
'@tokenizer/inflate@0.4.1':
'@tokenizer/inflate@0.4.1(supports-color@5.5.0)':
dependencies:
debug: 4.4.3
debug: 4.4.3(supports-color@5.5.0)
token-types: 6.1.2
transitivePeerDependencies:
- supports-color
@@ -3047,15 +3057,15 @@ snapshots:
'@types/http-errors': 2.0.5
'@types/node': 25.9.2
'@typescript-eslint/eslint-plugin@8.66.0(@typescript-eslint/parser@8.66.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5)(typescript@5.9.3)':
'@typescript-eslint/eslint-plugin@8.67.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(supports-color@5.5.0))(supports-color@5.5.0)(typescript@5.9.3))(eslint@9.39.5(supports-color@5.5.0))(supports-color@5.5.0)(typescript@5.9.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
'@typescript-eslint/parser': 8.66.0(eslint@9.39.5)(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.66.0
'@typescript-eslint/type-utils': 8.66.0(eslint@9.39.5)(typescript@5.9.3)
'@typescript-eslint/utils': 8.66.0(eslint@9.39.5)(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.66.0
eslint: 9.39.5
'@typescript-eslint/parser': 8.67.0(eslint@9.39.5(supports-color@5.5.0))(supports-color@5.5.0)(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.67.0
'@typescript-eslint/type-utils': 8.67.0(eslint@9.39.5(supports-color@5.5.0))(supports-color@5.5.0)(typescript@5.9.3)
'@typescript-eslint/utils': 8.67.0(eslint@9.39.5(supports-color@5.5.0))(supports-color@5.5.0)(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.67.0
eslint: 9.39.5(supports-color@5.5.0)
ignore: 7.0.6
natural-compare: 1.4.0
ts-api-utils: 2.5.0(typescript@5.9.3)
@@ -3063,57 +3073,57 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/parser@8.66.0(eslint@9.39.5)(typescript@5.9.3)':
'@typescript-eslint/parser@8.67.0(eslint@9.39.5(supports-color@5.5.0))(supports-color@5.5.0)(typescript@5.9.3)':
dependencies:
'@typescript-eslint/scope-manager': 8.66.0
'@typescript-eslint/types': 8.66.0
'@typescript-eslint/typescript-estree': 8.66.0(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.66.0
debug: 4.4.3
eslint: 9.39.5
'@typescript-eslint/scope-manager': 8.67.0
'@typescript-eslint/types': 8.67.0
'@typescript-eslint/typescript-estree': 8.67.0(supports-color@5.5.0)(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.67.0
debug: 4.4.3(supports-color@5.5.0)
eslint: 9.39.5(supports-color@5.5.0)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/project-service@8.66.0(typescript@5.9.3)':
'@typescript-eslint/project-service@8.67.0(supports-color@5.5.0)(typescript@5.9.3)':
dependencies:
'@typescript-eslint/tsconfig-utils': 8.66.0(typescript@5.9.3)
'@typescript-eslint/types': 8.66.0
debug: 4.4.3
'@typescript-eslint/tsconfig-utils': 8.67.0(typescript@5.9.3)
'@typescript-eslint/types': 8.67.0
debug: 4.4.3(supports-color@5.5.0)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/scope-manager@8.66.0':
'@typescript-eslint/scope-manager@8.67.0':
dependencies:
'@typescript-eslint/types': 8.66.0
'@typescript-eslint/visitor-keys': 8.66.0
'@typescript-eslint/types': 8.67.0
'@typescript-eslint/visitor-keys': 8.67.0
'@typescript-eslint/tsconfig-utils@8.66.0(typescript@5.9.3)':
'@typescript-eslint/tsconfig-utils@8.67.0(typescript@5.9.3)':
dependencies:
typescript: 5.9.3
'@typescript-eslint/type-utils@8.66.0(eslint@9.39.5)(typescript@5.9.3)':
'@typescript-eslint/type-utils@8.67.0(eslint@9.39.5(supports-color@5.5.0))(supports-color@5.5.0)(typescript@5.9.3)':
dependencies:
'@typescript-eslint/types': 8.66.0
'@typescript-eslint/typescript-estree': 8.66.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.66.0(eslint@9.39.5)(typescript@5.9.3)
debug: 4.4.3
eslint: 9.39.5
'@typescript-eslint/types': 8.67.0
'@typescript-eslint/typescript-estree': 8.67.0(supports-color@5.5.0)(typescript@5.9.3)
'@typescript-eslint/utils': 8.67.0(eslint@9.39.5(supports-color@5.5.0))(supports-color@5.5.0)(typescript@5.9.3)
debug: 4.4.3(supports-color@5.5.0)
eslint: 9.39.5(supports-color@5.5.0)
ts-api-utils: 2.5.0(typescript@5.9.3)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/types@8.66.0': {}
'@typescript-eslint/types@8.67.0': {}
'@typescript-eslint/typescript-estree@8.66.0(typescript@5.9.3)':
'@typescript-eslint/typescript-estree@8.67.0(supports-color@5.5.0)(typescript@5.9.3)':
dependencies:
'@typescript-eslint/project-service': 8.66.0(typescript@5.9.3)
'@typescript-eslint/tsconfig-utils': 8.66.0(typescript@5.9.3)
'@typescript-eslint/types': 8.66.0
'@typescript-eslint/visitor-keys': 8.66.0
debug: 4.4.3
'@typescript-eslint/project-service': 8.67.0(supports-color@5.5.0)(typescript@5.9.3)
'@typescript-eslint/tsconfig-utils': 8.67.0(typescript@5.9.3)
'@typescript-eslint/types': 8.67.0
'@typescript-eslint/visitor-keys': 8.67.0
debug: 4.4.3(supports-color@5.5.0)
minimatch: 10.2.6
semver: 7.8.5
tinyglobby: 0.2.17
@@ -3122,20 +3132,20 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@typescript-eslint/utils@8.66.0(eslint@9.39.5)(typescript@5.9.3)':
'@typescript-eslint/utils@8.67.0(eslint@9.39.5(supports-color@5.5.0))(supports-color@5.5.0)(typescript@5.9.3)':
dependencies:
'@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5)
'@typescript-eslint/scope-manager': 8.66.0
'@typescript-eslint/types': 8.66.0
'@typescript-eslint/typescript-estree': 8.66.0(typescript@5.9.3)
eslint: 9.39.5
'@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(supports-color@5.5.0))
'@typescript-eslint/scope-manager': 8.67.0
'@typescript-eslint/types': 8.67.0
'@typescript-eslint/typescript-estree': 8.67.0(supports-color@5.5.0)(typescript@5.9.3)
eslint: 9.39.5(supports-color@5.5.0)
typescript: 5.9.3
transitivePeerDependencies:
- supports-color
'@typescript-eslint/visitor-keys@8.66.0':
'@typescript-eslint/visitor-keys@8.67.0':
dependencies:
'@typescript-eslint/types': 8.66.0
'@typescript-eslint/types': 8.67.0
eslint-visitor-keys: 5.0.1
'@unblockneteasemusic/server@0.28.0':
@@ -3164,9 +3174,9 @@ snapshots:
acorn@8.18.0: {}
agent-base@6.0.2:
agent-base@6.0.2(supports-color@5.5.0):
dependencies:
debug: 4.4.3
debug: 4.4.3(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@@ -3187,7 +3197,7 @@ snapshots:
ansi-regex@5.0.1: {}
ansi-regex@6.2.2: {}
ansi-regex@6.3.0: {}
ansi-styles@3.2.1:
dependencies:
@@ -3252,11 +3262,11 @@ snapshots:
dependencies:
possible-typed-array-names: 1.1.0
axios@1.19.0:
axios@1.19.0(debug@4.4.3(supports-color@5.5.0))(supports-color@5.5.0):
dependencies:
follow-redirects: 1.16.0
follow-redirects: 1.16.0(debug@4.4.3(supports-color@5.5.0))
form-data: 4.0.6
https-proxy-agent: 5.0.1
https-proxy-agent: 5.0.1(supports-color@5.5.0)
proxy-from-env: 2.1.0
transitivePeerDependencies:
- debug
@@ -3278,11 +3288,11 @@ snapshots:
inherits: 2.0.4
readable-stream: 3.6.2
body-parser@1.20.6:
body-parser@1.20.6(supports-color@5.5.0):
dependencies:
bytes: 3.1.2
content-type: 1.0.5
debug: 2.6.9
debug: 2.6.9(supports-color@5.5.0)
depd: 2.0.0
destroy: 1.2.0
http-errors: 2.0.1
@@ -3295,11 +3305,11 @@ snapshots:
transitivePeerDependencies:
- supports-color
body-parser@2.3.0:
body-parser@2.3.0(supports-color@5.5.0):
dependencies:
bytes: 3.1.2
content-type: 2.0.0
debug: 4.4.3
content-type: 2.1.0
debug: 4.4.3(supports-color@5.5.0)
http-errors: 2.0.1
iconv-lite: 0.7.3
on-finished: 2.4.1
@@ -3465,7 +3475,7 @@ snapshots:
content-type@1.0.5: {}
content-type@2.0.0: {}
content-type@2.1.0: {}
convert-source-map@1.9.0: {}
@@ -3524,13 +3534,11 @@ snapshots:
dateformat@4.6.3: {}
debug@2.6.9:
debug@2.6.9(supports-color@5.5.0):
dependencies:
ms: 2.0.0
debug@4.4.3:
dependencies:
ms: 2.1.3
optionalDependencies:
supports-color: 5.5.0
debug@4.4.3(supports-color@5.5.0):
dependencies:
@@ -3842,22 +3850,22 @@ snapshots:
esrecurse: 4.3.0
estraverse: 4.3.0
eslint-config-prettier@10.1.8(eslint@9.39.5):
eslint-config-prettier@10.1.8(eslint@9.39.5(supports-color@5.5.0)):
dependencies:
eslint: 9.39.5
eslint: 9.39.5(supports-color@5.5.0)
eslint-plugin-html@8.1.4:
dependencies:
htmlparser2: 10.1.0
eslint-plugin-prettier@5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5))(eslint@9.39.5)(prettier@3.9.6):
eslint-plugin-prettier@5.5.6(eslint-config-prettier@10.1.8(eslint@9.39.5(supports-color@5.5.0)))(eslint@9.39.5(supports-color@5.5.0))(prettier@3.9.6):
dependencies:
eslint: 9.39.5
eslint: 9.39.5(supports-color@5.5.0)
prettier: 3.9.6
prettier-linter-helpers: 1.0.1
synckit: 0.11.13
optionalDependencies:
eslint-config-prettier: 10.1.8(eslint@9.39.5)
eslint-config-prettier: 10.1.8(eslint@9.39.5(supports-color@5.5.0))
eslint-scope@8.4.0:
dependencies:
@@ -3870,14 +3878,14 @@ snapshots:
eslint-visitor-keys@5.0.1: {}
eslint@9.39.5:
eslint@9.39.5(supports-color@5.5.0):
dependencies:
'@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5)
'@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(supports-color@5.5.0))
'@eslint-community/regexpp': 4.12.2
'@eslint/config-array': 0.21.2
'@eslint/config-array': 0.21.2(supports-color@5.5.0)
'@eslint/config-helpers': 0.4.2
'@eslint/core': 0.17.0
'@eslint/eslintrc': 3.3.6
'@eslint/eslintrc': 3.3.6(supports-color@5.5.0)
'@eslint/js': 9.39.5
'@eslint/plugin-kit': 0.4.1
'@humanfs/node': 0.16.8
@@ -3887,7 +3895,7 @@ snapshots:
ajv: 6.15.0
chalk: 4.1.2
cross-spawn: 7.0.6
debug: 4.4.3
debug: 4.4.3(supports-color@5.5.0)
escape-string-regexp: 4.0.0
eslint-scope: 8.4.0
eslint-visitor-keys: 4.2.1
@@ -4000,21 +4008,21 @@ snapshots:
dependencies:
busboy: 1.6.0
express@4.22.2:
express@4.22.2(supports-color@5.5.0):
dependencies:
accepts: 1.3.8
array-flatten: 1.1.1
body-parser: 1.20.6
body-parser: 1.20.6(supports-color@5.5.0)
content-disposition: 0.5.4
content-type: 1.0.5
cookie: 0.7.2
cookie-signature: 1.0.7
debug: 2.6.9
debug: 2.6.9(supports-color@5.5.0)
depd: 2.0.0
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
finalhandler: 1.3.2
finalhandler: 1.3.2(supports-color@5.5.0)
fresh: 0.5.2
http-errors: 2.0.1
merge-descriptors: 1.0.3
@@ -4026,8 +4034,8 @@ snapshots:
qs: 6.15.3
range-parser: 1.2.1
safe-buffer: 5.2.1
send: 0.19.2
serve-static: 1.16.3
send: 0.19.2(supports-color@5.5.0)
serve-static: 1.16.3(supports-color@5.5.0)
setprototypeof: 1.2.0
statuses: 2.0.2
type-is: 1.6.18
@@ -4036,20 +4044,20 @@ snapshots:
transitivePeerDependencies:
- supports-color
express@5.2.1:
express@5.2.1(supports-color@5.5.0):
dependencies:
accepts: 2.0.0
body-parser: 2.3.0
body-parser: 2.3.0(supports-color@5.5.0)
content-disposition: 1.1.0
content-type: 1.0.5
cookie: 0.7.2
cookie-signature: 1.2.2
debug: 4.4.3
debug: 4.4.3(supports-color@5.5.0)
depd: 2.0.0
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
finalhandler: 2.1.1
finalhandler: 2.1.1(supports-color@5.5.0)
fresh: 2.0.0
http-errors: 2.0.1
merge-descriptors: 2.0.0
@@ -4060,9 +4068,9 @@ snapshots:
proxy-addr: 2.0.7
qs: 6.15.3
range-parser: 1.3.0
router: 2.2.0
send: 1.2.1
serve-static: 2.2.1
router: 2.2.0(supports-color@5.5.0)
send: 1.2.1(supports-color@5.5.0)
serve-static: 2.2.1(supports-color@5.5.0)
statuses: 2.0.2
type-is: 2.1.0
vary: 1.1.2
@@ -4105,9 +4113,9 @@ snapshots:
dependencies:
flat-cache: 4.0.1
file-type@21.3.4:
file-type@21.3.4(supports-color@5.5.0):
dependencies:
'@tokenizer/inflate': 0.4.1
'@tokenizer/inflate': 0.4.1(supports-color@5.5.0)
strtok3: 10.3.5
token-types: 6.1.2
uint8array-extras: 1.5.0
@@ -4118,9 +4126,9 @@ snapshots:
dependencies:
to-regex-range: 5.0.1
finalhandler@1.3.2:
finalhandler@1.3.2(supports-color@5.5.0):
dependencies:
debug: 2.6.9
debug: 2.6.9(supports-color@5.5.0)
encodeurl: 2.0.0
escape-html: 1.0.3
on-finished: 2.4.1
@@ -4130,9 +4138,9 @@ snapshots:
transitivePeerDependencies:
- supports-color
finalhandler@2.1.1:
finalhandler@2.1.1(supports-color@5.5.0):
dependencies:
debug: 4.4.3
debug: 4.4.3(supports-color@5.5.0)
encodeurl: 2.0.0
escape-html: 1.0.3
on-finished: 2.4.1
@@ -4162,7 +4170,9 @@ snapshots:
flatted@3.4.4: {}
follow-redirects@1.16.0: {}
follow-redirects@1.16.0(debug@4.4.3(supports-color@5.5.0)):
optionalDependencies:
debug: 4.4.3(supports-color@5.5.0)
for-each@0.3.5:
dependencies:
@@ -4250,11 +4260,11 @@ snapshots:
es-errors: 1.3.0
get-intrinsic: 1.3.0
get-uri@6.0.5:
get-uri@6.0.5(supports-color@5.5.0):
dependencies:
basic-ftp: 5.3.1
data-uri-to-buffer: 6.0.2
debug: 4.4.3
debug: 4.4.3(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@@ -4279,7 +4289,7 @@ snapshots:
globals@14.0.0: {}
globals@17.9.0: {}
globals@17.11.0: {}
globalthis@1.0.4:
dependencies:
@@ -4348,24 +4358,24 @@ snapshots:
statuses: 2.0.2
toidentifier: 1.0.1
http-proxy-agent@7.0.2:
http-proxy-agent@7.0.2(supports-color@5.5.0):
dependencies:
agent-base: 7.1.4
debug: 4.4.3
debug: 4.4.3(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
https-proxy-agent@5.0.1:
https-proxy-agent@5.0.1(supports-color@5.5.0):
dependencies:
agent-base: 6.0.2
debug: 4.4.3
agent-base: 6.0.2(supports-color@5.5.0)
debug: 4.4.3(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
https-proxy-agent@7.0.6:
https-proxy-agent@7.0.6(supports-color@5.5.0):
dependencies:
agent-base: 7.1.4
debug: 4.4.3
debug: 4.4.3(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@@ -4421,7 +4431,7 @@ snapshots:
from2: 2.3.0
p-is-promise: 3.0.0
ip-address@10.4.0: {}
ip-address@10.5.0: {}
ipaddr.js@1.9.1: {}
@@ -4586,15 +4596,15 @@ snapshots:
dependencies:
argparse: 2.0.1
jsdom@24.1.3:
jsdom@24.1.3(supports-color@5.5.0):
dependencies:
cssstyle: 4.6.0
data-urls: 5.0.0
decimal.js: 10.6.0
form-data: 4.0.6
html-encoding-sniffer: 4.0.0
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
http-proxy-agent: 7.0.2(supports-color@5.5.0)
https-proxy-agent: 7.0.6(supports-color@5.5.0)
is-potential-custom-element-name: 1.0.1
nwsapi: 2.2.24
parse5: 7.3.0
@@ -4607,7 +4617,7 @@ snapshots:
whatwg-encoding: 3.1.1
whatwg-mimetype: 4.0.0
whatwg-url: 14.2.0
ws: 8.21.2
ws: 8.21.3
xml-name-validator: 5.0.0
transitivePeerDependencies:
- bufferutil
@@ -4787,13 +4797,13 @@ snapshots:
once: 1.4.0
readable-stream: 3.6.2
music-metadata@11.14.0:
music-metadata@11.14.0(supports-color@5.5.0):
dependencies:
'@borewit/text-codec': 0.2.2
'@tokenizer/token': 0.3.0
content-type: 2.0.0
debug: 4.4.3
file-type: 21.3.4
content-type: 2.1.0
debug: 4.4.3(supports-color@5.5.0)
file-type: 21.3.4(supports-color@5.5.0)
media-typer: 2.0.0
strtok3: 10.3.5
token-types: 6.1.2
@@ -4923,16 +4933,16 @@ snapshots:
p-try@2.2.0: {}
pac-proxy-agent@7.2.0:
pac-proxy-agent@7.2.0(supports-color@5.5.0):
dependencies:
'@tootallnate/quickjs-emscripten': 0.23.0
agent-base: 7.1.4
debug: 4.4.3
get-uri: 6.0.5
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.6
debug: 4.4.3(supports-color@5.5.0)
get-uri: 6.0.5(supports-color@5.5.0)
http-proxy-agent: 7.0.2(supports-color@5.5.0)
https-proxy-agent: 7.0.6(supports-color@5.5.0)
pac-resolver: 7.0.1
socks-proxy-agent: 8.0.5
socks-proxy-agent: 8.0.5(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@@ -5011,11 +5021,11 @@ snapshots:
quick-format-unescaped: 4.0.4
sonic-boom: 1.4.1
pkg-fetch@3.4.2:
pkg-fetch@3.4.2(supports-color@5.5.0):
dependencies:
chalk: 4.1.2
fs-extra: 9.1.0
https-proxy-agent: 5.0.1
https-proxy-agent: 5.0.1(supports-color@5.5.0)
node-fetch: 2.7.0
progress: 2.0.3
semver: 7.8.5
@@ -5025,7 +5035,7 @@ snapshots:
- encoding
- supports-color
pkg@5.8.1:
pkg@5.8.1(supports-color@5.5.0):
dependencies:
'@babel/generator': 7.18.2
'@babel/parser': 7.18.4
@@ -5037,7 +5047,7 @@ snapshots:
is-core-module: 2.9.0
minimist: 1.2.8
multistream: 4.1.0
pkg-fetch: 3.4.2
pkg-fetch: 3.4.2(supports-color@5.5.0)
prebuild-install: 7.1.1
resolve: 1.22.12
stream-meter: 1.0.4
@@ -5278,9 +5288,9 @@ snapshots:
rfdc@1.4.1: {}
router@2.2.0:
router@2.2.0(supports-color@5.5.0):
dependencies:
debug: 4.4.3
debug: 4.4.3(supports-color@5.5.0)
depd: 2.0.0
is-promise: 4.0.0
parseurl: 1.3.3
@@ -5333,9 +5343,9 @@ snapshots:
semver@7.8.5: {}
send@0.19.2:
send@0.19.2(supports-color@5.5.0):
dependencies:
debug: 2.6.9
debug: 2.6.9(supports-color@5.5.0)
depd: 2.0.0
destroy: 1.2.0
encodeurl: 2.0.0
@@ -5351,9 +5361,9 @@ snapshots:
transitivePeerDependencies:
- supports-color
send@1.2.1:
send@1.2.1(supports-color@5.5.0):
dependencies:
debug: 4.4.3
debug: 4.4.3(supports-color@5.5.0)
encodeurl: 2.0.0
escape-html: 1.0.3
etag: 1.8.1
@@ -5371,21 +5381,21 @@ snapshots:
dependencies:
randombytes: 2.1.0
serve-static@1.16.3:
serve-static@1.16.3(supports-color@5.5.0):
dependencies:
encodeurl: 2.0.0
escape-html: 1.0.3
parseurl: 1.3.3
send: 0.19.2
send: 0.19.2(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
serve-static@2.2.1:
serve-static@2.2.1(supports-color@5.5.0):
dependencies:
encodeurl: 2.0.0
escape-html: 1.0.3
parseurl: 1.3.3
send: 1.2.1
send: 1.2.1(supports-color@5.5.0)
transitivePeerDependencies:
- supports-color
@@ -5477,17 +5487,17 @@ snapshots:
smart-buffer@4.2.0: {}
socks-proxy-agent@8.0.5:
socks-proxy-agent@8.0.5(supports-color@5.5.0):
dependencies:
agent-base: 7.1.4
debug: 4.4.3
debug: 4.4.3(supports-color@5.5.0)
socks: 2.8.9
transitivePeerDependencies:
- supports-color
socks@2.8.9:
dependencies:
ip-address: 10.4.0
ip-address: 10.5.0
smart-buffer: 4.2.0
sonic-boom@1.4.1:
@@ -5598,7 +5608,7 @@ snapshots:
strip-ansi@7.2.0:
dependencies:
ansi-regex: 6.2.2
ansi-regex: 6.3.0
strip-json-comments@2.0.1: {}
@@ -5712,7 +5722,7 @@ snapshots:
type-is@2.1.0:
dependencies:
content-type: 2.0.0
content-type: 2.1.0
media-typer: 1.1.1
mime-types: 3.0.2
@@ -5909,7 +5919,7 @@ snapshots:
wrappy@1.0.2: {}
ws@8.21.2: {}
ws@8.21.3: {}
xml-name-validator@5.0.0: {}
+5
View File
@@ -0,0 +1,5 @@
packages:
- '.'
minimumReleaseAgeExclude:
- '@neteasecloudmusicapienhanced/unblockmusic-utils@0.4.2'
+38 -6
View File
@@ -1304,14 +1304,14 @@ tags: 歌单标签
**必选参数 :** `id` : 音乐 id
`level`: 播放音质等级, 分为 `standard` => `标准`,`higher` => `较高`, `exhigh`=>`极高`,
`lossless`=>`无损`, `hires`=>`Hi-Res`, `jyeffect` => `高清环绕声`, `sky` => `沉浸环绕声`, `dolby` => `杜比全景声`, `jymaster` => `超清母带`
`lossless`=>`无损`, `hires`=>`Hi-Res`, `jyeffect` => `高清环绕声`, `sky` => `沉浸环绕声`, `vivid` => `臻音全景声`, `dolby` => `杜比全景声`, `jymaster` => `超清母带`
`unblock`: 是否使用使用歌曲解锁, 分为`true`和`false`
**可选参数 :** `immerseType`: 沉浸声环绕声类型, 分为 `c51` => `c51类型`, `ste` => `环绕立体声类型`, `aac` => `aac类型`, 仅在 `level=sky` 时生效, 默认为 `c51`
**接口地址 :** `/song/url/v1`
**调用例子 :** `/song/url/v1?id=1969519579&level=exhigh` `/song/url/v1?id=1969519579,33894312&level=lossless` `/song/url/v1?id=1969519579&level=sky&immerseType=ste`
**调用例子 :** `/song/url/v1?id=1969519579&level=exhigh` `/song/url/v1?id=1969519579,33894312&level=lossless` `/song/url/v1?id=1969519579&level=sky&immerseType=ste` `/song/url/v1?id=1969519579&level=vivid`
说明:`杜比全景声`音质需要设备支持,不同的设备可能会返回不同码率的 url。cookie 需要传入`os=pc`保证返回正常码率的 url。
@@ -1321,7 +1321,7 @@ tags: 歌单标签
**必选参数 :** `id` : 音乐 id
`level`: 播放音质等级, 分为 `standard` => `标准`,`higher` => `较高`, `exhigh`=>`极高`,
`lossless`=>`无损`, `hires`=>`Hi-Res`, `jyeffect` => `高清环绕声`, `sky` => `沉浸环绕声`, `dolby` => `杜比全景声`, `jymaster` => `超清母带`
`lossless`=>`无损`, `hires`=>`Hi-Res`, `jyeffect` => `高清环绕声`, `sky` => `沉浸环绕声`, `vivid` => `臻音全景声`, `dolby` => `杜比全景声`, `jymaster` => `超清母带`
`unblock`: 是否使用使用歌曲解锁, 分为`true`和`false`
**接口地址 :** `/song/url/v1/302`
@@ -2473,6 +2473,18 @@ privilege:权限相关信息
喜欢成功则返回数据的 code 为 200, 其余为失败
### 喜欢音乐 - 新版
说明: 调用此接口 , 传入音乐 id, 可喜欢该音乐
**必选参数 :** `id`: 歌曲 id
**可选参数 :** `like`: 布尔值 , 默认为 true 即喜欢 , 若传 false, 则取消喜欢
**接口地址 :** `/like/v1`
**调用例子 :** `/like/v1?id=347230`
### 喜欢音乐列表
说明 : 调用此接口 , 传入用户 id, 可获取已喜欢音乐 id 列表(id 数组)
@@ -4138,6 +4150,16 @@ type='1009' 获取其 id, 如`/search?keywords= 代码时间 &type=1009`
**调用例子:** `/song/wiki/summary?id=1958384591`
### 音乐百科
说明: 调用此接口可以获取歌曲的音乐百科信息
**接口地址:** `/song/wiki/info`
**必选参数:** `id`: 歌曲 ID
**调用例子:** `/song/wiki/info?id=1958384591`
### 乐谱列表
说明: 调用此接口可以获取歌曲的乐谱列表
@@ -4690,11 +4712,11 @@ qrCodeStatus:20,detailReason:0 验证成功 qrCodeStatus:21,detailReason:0 二
**必选参数:**
`mode`: 模式 (aidj, DEFAULT, FAMILIAR, EXPLORE, SCENE_RCMD)
`mode`: 模式 (`DEFAULT`: 默认模式,`FAMILIAR`: 熟悉模式,`EXPLORE`: 探索模式,`SCENE_RCMD`: 场景模式, 需要传入`submode`参数,`PUZZLE_MODE_RCMD`: 拼图模式)
**可选参数:**
`submode`: 当 mode 为 SCENE_RCMD 是可为 ( EXERCISE, FOCUS, NIGHT_EMO )
`submode`: 当 mode 为 SCENE_RCMD 时传入 ( `EXERCISE`: 运动, `FOCUS`: 专注, `NIGHT_EMO`: 伤感, `SLEEP_HELP`: 助眠, `RELAX`: 放松, `CHEERFUL`: 欢快, `LYRICAL`: 抒情, `CURE`: 治愈, `SWEET`: 情歌, `RHYTHM_BLUES`: R&B, `RAINY`: 雨天, `GAMES`: 游戏, `RAP`: 说唱, `K_POP`: K-Pop, `ORIGINAL_MUSICIAL`: 宝藏原创, `ELECTRONIC`: 电音, `COMMUTE`: 出行, `TAKE_SHOWER`: 洗澡, `COFFEE_SHOP`: 咖啡馆, `ROCK`: 摇滚, `INSPIRATIONAL`: 励志, `CHINESE`: 华语, `ENGLISH`: 欧美, `YUEYU`: 粤语, `MANYAO`: 慢摇DJ, `JINGDIAN`: 经典, `LIGHT`: 轻音乐, `GUOFENG`: 国风, `FOLK`: 民谣, `ACG`: 二次元, `GUDIAN`: 古典, `JAZZ`: 爵士, `JAPANESE`: 日语, `GLOBAL`: 全球, `FRANCH`: 法语, `BLUE`: 蓝调, `DANCE`: 舞蹈, `LATIN`: 拉丁, `PUNK`: 放克, `COUNTRY`: 乡村乐, `MUSICAL`: 音乐剧, `YINGSHI`: 影视)
**接口地址:** `/personal/fm/mode`
@@ -4774,7 +4796,7 @@ bitrate = Math.floor(br / 1000)
**必选参数 :** `id` : 音乐 id
`level`: 播放音质等级, 分为 `standard` => `标准`,`higher` => `较高`, `exhigh`=>`极高`,
`lossless`=>`无损`, `hires`=>`Hi-Res`, `jyeffect` => `高清环绕声`, `sky` => `沉浸环绕声`, `dolby` => `杜比全景声`, `jymaster` => `超清母带`
`lossless`=>`无损`, `hires`=>`Hi-Res`, `jyeffect` => `高清环绕声`, `sky` => `沉浸环绕声`, `vivid` => `臻音全景声`, `dolby` => `杜比全景声`, `jymaster` => `超清母带`
**接口地址 :** `/song/download/url/v1`
@@ -5834,6 +5856,16 @@ let data = encodeURIComponent(
**调用例子 :** `/device/kickoff?key=00ALDFGEXXXXXXXXXXXXXXXXX&captcha=1234`
### 插播相似歌曲
说明: 调用此接口, 传入歌曲 id, 可获取插播相似歌曲
**必选参数 :** `id`: 歌曲 id
**接口地址 :** `/song/simi/get`
**调用例子 :** `/song/simi/get?id=39227633`
## 离线访问此文档
此文档同时也是 Progressive Web Apps(PWA), 加入了 serviceWorker, 可离线访问
-204
View File
@@ -1,204 +0,0 @@
#!/usr/bin/env node
import { spawnSync } from 'node:child_process'
import { readFileSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
const eventName = process.env.GITHUB_EVENT_NAME
const eventPath = process.env.GITHUB_EVENT_PATH
const token = process.env.GITHUB_TOKEN
const repo = process.env.GITHUB_REPOSITORY
const model = process.env.MODEL || 'opencode/deepseek-v4-flash-free'
const botLogin = process.env.BOT_LOGIN || 'takanashi-hoshino-agent[bot]'
if (!eventPath || !token || !repo) {
console.error(
'Missing required env: GITHUB_EVENT_PATH / GITHUB_TOKEN / GITHUB_REPOSITORY',
)
process.exit(1)
}
if (!process.env.OPENCODE_API_KEY) {
console.error('Missing OPENCODE_API_KEY')
process.exit(1)
}
const event = JSON.parse(readFileSync(eventPath, 'utf8'))
const [owner, repoName] = repo.split('/')
const api = `https://api.github.com/repos/${owner}/${repoName}`
const headers = {
Authorization: `Bearer ${token}`,
Accept: 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
'User-Agent': 'opencode-automation',
}
async function get(path) {
const res = await fetch(`${api}${path}`, { headers })
if (!res.ok) throw new Error(`GET ${path}: HTTP ${res.status}`)
return res.json()
}
async function post(path, body) {
const res = await fetch(`${api}${path}`, {
method: 'POST',
headers,
body: JSON.stringify(body),
})
const text = await res.text()
if (!res.ok) throw new Error(`POST ${path}: HTTP ${res.status} ${text}`)
return text ? JSON.parse(text) : null
}
/** 无头模式跑 opencode,返回模型输出的文本 */
function runOpencode(prompt, contextFile) {
const args = ['run', '--auto', '-m', model, '--format', 'default', prompt]
if (contextFile) args.push('-f', contextFile)
console.log(
`Running: opencode run --auto -m ${model} (prompt ${prompt.length} chars${contextFile ? ', context attached' : ''})`,
)
const res = spawnSync('opencode', args, {
encoding: 'utf8',
maxBuffer: 128 * 1024 * 1024,
})
if (res.error) throw res.error
if (res.status !== 0) {
if (res.stderr) console.error('opencode stderr:\n' + res.stderr)
throw new Error(`opencode exited with code ${res.status}`)
}
return (res.stdout || '').trim()
}
/** 该 issue/PR 是否已有 bot 评论(用于去重,避免 synchronize 重复评论) */
async function hasBotComment(target) {
const comments = await get(`/issues/${target}/comments?per_page=100`)
return comments.some((c) => c.user?.login === botLogin)
}
async function comment(target, body) {
if (!body) {
console.log('No output from agent, skip comment')
return
}
if (body.length > 60000) body = body.slice(0, 60000) + '\n\n_...(truncated)_'
await post(`/issues/${target}/comments`, { body })
console.log(`Commented on #${target}`)
}
async function handleIssue(issue) {
const n = issue.number
console.log(`Handling issue #${n}`)
if (await hasBotComment(n)) {
console.log(`Already handled by bot, skip`)
return
}
const comments = await get(`/issues/${n}/comments?per_page=100`)
const thread = comments
.filter((c) => c.user?.login !== botLogin)
.map(
(c) =>
`- **${c.user?.login}** (${c.created_at}):\n ${(c.body || '').replace(/\n/g, '\n ')}`,
)
.join('\n')
const ctx = [
`# Issue #${n}: ${issue.title}`,
``,
`- State: ${issue.state}`,
`- Author: ${issue.user?.login}`,
`- Created: ${issue.created_at}`,
``,
`## Body`,
``,
issue.body || '(empty)',
...(thread ? [`\n## Comments\n\n${thread}`] : []),
].join('\n')
const ctxFile = join(tmpdir(), 'opencode-issue-context.md')
writeFileSync(ctxFile, ctx)
const prompt =
process.env.ISSUE_PROMPT ||
[
`You are a maintainer bot for the ${repo} repository.`,
`Read the attached file for the issue context.`,
`If the issue has a clear fix or points to relevant docs, reply with documentation links and/or`,
`error-handling guidance for code examples. If nothing actionable, reply with exactly "NO_ACTION".`,
`Do NOT modify any files, do NOT commit, do NOT push. Output only the comment text.`,
].join('\n')
const output = runOpencode(prompt, ctxFile)
if (output === 'NO_ACTION' || output.startsWith('NO_ACTION')) {
console.log('Agent decided no action needed')
return
}
await comment(n, output)
}
async function handlePullRequest(pr) {
const n = pr.number
console.log(`Handling PR #${n}`)
if (await hasBotComment(n)) {
console.log(`Already handled by bot, skip`)
return
}
let files = []
try {
files = await get(`/pulls/${n}/files?per_page=100`)
} catch (e) {
console.warn(`Failed to fetch changed files: ${e.message}`)
}
const fileList = files
.map((f) => `- ${f.status} ${f.filename} (+${f.additions}/-${f.deletions})`)
.join('\n')
const ctx = [
`# PR #${n}: ${pr.title}`,
``,
`- State: ${pr.state}`,
`- Author: ${pr.user?.login}`,
`- Base: ${pr.base?.ref} <- Head: ${pr.head?.ref}`,
`- Created: ${pr.created_at}`,
`- Stats: +${pr.additions}/-${pr.deletions}, ${pr.changed_files} files`,
``,
`## Body`,
``,
pr.body || '(empty)',
...(fileList ? [`\n## Changed files\n\n${fileList}`] : []),
].join('\n')
const ctxFile = join(tmpdir(), 'opencode-pr-context.md')
writeFileSync(ctxFile, ctx)
const prompt =
process.env.PR_PROMPT ||
[
`You are a maintainer bot for the ${repo} repository.`,
`Read the attached file for the PR context. The PR branch is already checked out.`,
`Run \`git diff HEAD^1 HEAD\` (or \`git diff origin/${pr.base?.ref}...HEAD\`) to see the changes.`,
`Review the code changes: point out bugs, risks and improvements, and suggest fixes for obvious issues.`,
`If the PR looks good, say so concisely.`,
`Do NOT modify any files, do NOT commit, do NOT push. Output only the review comment text.`,
].join('\n')
const output = runOpencode(prompt, ctxFile)
await comment(n, output)
}
async function main() {
console.log(`Event: ${eventName} on ${repo}`)
if (eventName === 'issues') {
await handleIssue(event.issue)
} else if (eventName === 'pull_request') {
await handlePullRequest(event.pull_request)
} else {
console.log(`Unhandled event type: ${eventName}`)
}
}
main().catch((e) => {
console.error(`Automation failed: ${e.message}`)
process.exit(1)
})