Compare commits

...

2 Commits

Author SHA1 Message Date
6732fc7c32
ci(test): test ci workflow file 2026-07-31 22:21:34 +08:00
6ce6b84015
fix: 修复分享笔记接口 2026-07-26 22:39:58 +08:00
5 changed files with 117 additions and 21 deletions

5
.codegraph/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
# CodeGraph data files — local to each machine, not for committing.
# Ignore everything in .codegraph/ except this file itself, so transient
# files (the database, daemon.pid, sockets, logs) never show up in git.
*
!.gitignore

67
.github/workflows/ci-check.yml vendored Normal file
View File

@ -0,0 +1,67 @@
name: CI
on:
push:
branches: [main]
pull_request:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
check:
name: Lint / Unit / Docs
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 22, 24]
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: 9
- uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
cache: pnpm
# frozen-lockfile: 顺带校验 package.json 与 pnpm-lock.yaml 是否一致
- name: Install dependencies (frozen lockfile)
run: pnpm install --frozen-lockfile
- name: Lint
run: pnpm lint
# 纯单测,不需要网络,稳定必过
- name: Unit tests
run: pnpm exec mocha -r intelli-espower-loader -t 60000 main.test.js --exit
- name: Docs format check
run: pnpm docs:check
integration:
# server.test.js 会启动真实服务器并请求真实网易云 API
# 可能因上游风控/限流偶发失败,因此不阻塞合并
name: Integration tests (real NetEase API)
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: 9
- uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
- name: Install dependencies (frozen lockfile)
run: pnpm install --frozen-lockfile
- name: Run full test suite
run: pnpm test

View File

@ -1,23 +1,40 @@
# Agent Instructions for NeteaseCloudMusicApiEnhanced # NeteaseCloudMusicApiEnhanced Agent 说明
## Quick Start ## 快速开始
- **Package Manager**: Use `pnpm` (not npm or yarn). - **包管理器**:开发与 CI 使用 `pnpm``Dockerfile` 也用 pnpm`pnpm@9 --frozen-lockfile`,匹配 `pnpm-lock.yaml`)。仓库没有 `yarn.lock`,不要引入 yarn。
- **Node Version**: Requires Node.js 18 or later. - **Node 版本**README 推荐 Node 22+`package.json``engines` 声明 `>=12`CI/打包在 Node 1824 上运行。现代 Node 均可。
- **环境变量**`server.js` 调用了 `dotenv.config()`,本地 `.env` 会被自动加载;所有支持的变量见 `.env.prod.example`
## Developer Commands ## 常用命令
- **Install dependencies**: `pnpm i` - 安装依赖:`pnpm i`
- **Start server**: `pnpm start` or `node app.js` - 启动服务:`pnpm start`(等价 `node app.js`);热重载开发:`pnpm dev`nodemon
- **Start dev server**: `pnpm dev` (uses nodemon) - 跑测试:`pnpm test`Mocha超时 60s
- **Run tests**: `pnpm test` (uses Mocha) - Lint`pnpm lint`;自动修复:`pnpm lint-fix`
- **Linting**: `pnpm lint` (check) or `pnpm lint-fix` (auto-fix) - 文档格式化检查/修复:`pnpm docs:check` / `pnpm docs:format`
- 打包独立二进制:`pnpm pkgwin` / `pkglinux` / `pkgmacos`
## Architecture & Entrypoints ## 架构
- **Executable Server**: `app.js` is the main entrypoint for running the API server. - `app.js`(也是 `bin`)——服务入口。先确保 `os.tmpdir()` 里存在 `anonymous_token`,执行 `generateConfig()` 刷新匿名 cookie 与 xeapi 公钥,再调用 `server.serveNcmApi()`
- **Module Exports**: `main.js` is the entrypoint when the project is imported as a Node.js dependency. - `server.js`——Express 工厂。`constructServer()` 自动扫描 `module/*.js`,每个文件注册一条路由(文件名 `_``/`,如 `album_new.js``/album/new`;特例 `daily_signin`/`fm_trash`/`personal_fm` 硬编码在 `server.js``special` 对象里)。`serveNcmApi()` 监听 `PORT`(默认 3000/`HOST`
- **API Endpoints**: Located in the `module/` directory. Each file typically corresponds to an API route. - `main.js`——作为依赖被引入时的入口(`main` 字段)。把每个 `module/*` 导出为同名函数 `name(data)`,另导出 `server``serveNcmApi``getModulesDefinitions`
- **Core Utilities**: Request handling, encryption, and core utilities are found in the `util/` directory. - `module/*.js`——每个接口一个文件,标准写法:`module.exports = (query, request) => request(path, data, createOption(query))``createOption``util/option.js`,负责 crypto、cookie回退到 `NETEASE_COOKIE`、proxy、realIP/randomCNIP、headers、timeout。
- `util/request.js`——唯一的对外 HTTP 层axios。按 `crypto``api`/`eapi`/`weapi`/`linuxapi`/`xeapi`)加密并设置 IP 头;在 require 时同步读取 `os.tmpdir()` 里的 `anonymous_token``xeapi_public_key`
- `util/config.json`——运行时配置:网易域名 + `APP_CONF.encrypt: true`(默认走 eapi 加密)。已被 git 跟踪,改动会改变全局默认行为。
- `index.js` / `index.mjs`——`require('./app.js')` 的薄包装,供 Vercel`vercel.json`)和 ESM 导入使用。
## Important Gotchas & Quirks ## 新增/修改接口
- **Environment Variables**: The server defaults to port 3000 but can be overridden with the `PORT` environment variable. - 新建 `module/xxx.js` 会自动挂载路由,无需注册;**文件名即路由**。
- **Proxy Variables**: Be very careful with proxy environment variables (`http_proxy`, `https_proxy`, `no_proxy`). The request library (like axios) will automatically pick these up. If they point to an unavailable proxy (especially common in Docker environments), requests will fail silently or throw connection errors. - 照抄同目录模块的写法(选对 `crypto`),用 `createOption(query)` 生成请求选项。
- **Code Style**: The project uses ESLint and Prettier. Always run `pnpm lint-fix` before committing changes to ensure formatting consistency. - 改文件名/路由会破坏已有客户端,尽量保持旧路径兼容。
## 测试
- `pnpm test``server.test.js` + `main.test.js``server.test.js``before()` 里启动真实服务器,`test/*.test.js` 全部请求**真实网易云 API**——必须联网,且可能因上游风控/限流偶发失败。`main.test.js` 是纯单测。
- 测试使用 `power-assert`(经 `intelli-espower-loader`),普通 `assert` 写法也会输出详细 diff。
- 只跑单个用例:`pnpm exec mocha -r intelli-espower-loader -t 60000 --grep "<describe/it 名字>" server.test.js main.test.js --exit`
## 坑与注意
- **改 `package.json` 的 `version` 会触发自动发布**push 到 `main` 后会自动打 GitHub Release`pkg` 二进制)、构建并推送 Docker 镜像Docker Hub + GHCR`pnpm publish` 到 npm。别顺手改版本号。
- **没有实际 git hooks**`package.json` 里配了 `lint-staged`,但 `.husky/` 下没有真正的 hookcommit 时不会自动跑任何检查,自己记得 `pnpm lint-fix`
- **代理环境变量已失效**README 里关于 `http_proxy`/`https_proxy` 的警告来自旧 `request` 库时代;现在 `util/request.js` 用 axios + 自定义 keep-alive agent且显式 `proxy: false`,环境变量代理不会生效。按请求走 `query.proxy` 参数(支持 PAC 和 http 隧道)。
- **启动令牌在系统临时目录**`anonymous_token``xeapi_public_key` 存放在 `os.tmpdir()``util/request.js` 在 require 时同步读取。文件过期或被清空就重启服务(或调用 `generateConfig()`);首次启动先写空文件再刷新。
- **ESLint 9 flat config**`eslint.config.js`,风格由 `eslint-plugin-prettier` 强制2 空格缩进、单引号、分号、`endOfLine: auto`)。

View File

@ -3,13 +3,16 @@ FROM node:lts-alpine
RUN apk add --no-cache tini RUN apk add --no-cache tini
ENV NODE_ENV production ENV NODE_ENV production
RUN npm install -g pnpm@9
USER node USER node
WORKDIR /app WORKDIR /app
COPY --chown=node:node . ./ COPY --chown=node:node . ./
RUN yarn --network-timeout=100000 RUN pnpm install --frozen-lockfile --prod
EXPOSE 3000 EXPOSE 3000

View File

@ -7,5 +7,9 @@ module.exports = (query, request) => {
msg: query.msg || '', msg: query.msg || '',
id: query.id || '', id: query.id || '',
} }
return request(`/api/share/friends/resource`, data, createOption(query)) return request(
`/api/share/friends/resource`,
data,
createOption(query, 'xeapi', 'v3'),
)
} }