ali-quark-drive
v1.0.1
Published
Quark Cloud Drive CLI Tool - Node.js version
Maintainers
Readme
夸克网盘 CLI
夸克网盘命令行工具。
本项目仅用于学术研究、互操作性研究与合法自动化等场景。不得用于任何非法用途、滥用行为、未授权访问、批量爬取,或任何违反适用法律、平台规则及第三方权利的行为。
简体中文 | English
目录
功能特性
- TypeScript: 完整的 TypeScript 实现,严格类型检查
- 用户信息: 获取用户信息和网盘容量
- 文件列表: 列出目录内容,支持流式输出
- 文件信息: 获取文件/文件夹详情
- 下载: 获取文件下载链接
- 上传: 支持 MD5/SHA1 哈希的文件上传
- 文件夹操作: 创建文件夹
- 文件管理: 移动、复制、重命名、删除文件
- 分享: 创建、删除、列出、转存分享
- 认证: 使用 Playwright 浏览器自动登录获取 Cookie
- 管道模式: 支持 Unix 工具链式调用
- 测试: 包含 Jest 测试套件
安装
前置要求
- Node.js 20+ (推荐: 20.12.2 LTS)
- npm 10+
安装方式
方式 1:从 npm 安装(推荐)
# 安装到当前项目
npm install ali-quark-drive
# 安装 Playwright 浏览器
npx playwright install chromium安装后,可通过以下方式使用:
# 使用 npx
npx quark <命令>
# 或使用 npm exec
npm exec quark <命令>
# 或使用 yarn
yarn quark <命令>
# 或使用 pnpm
pnpm quark <命令>如果是全局安装,则可以直接运行 quark <命令>。
方式 2:全局安装
# 全局安装
npm install -g ali-quark-drive
# 或使用 yarn
yarn global add ali-quark-drive
# 或使用 pnpm
pnpm add -g ali-quark-drive全局安装后,直接使用:
quark <命令>开发
当前以 npm 包形式分发,暂不公开源码仓库地址。
快速开始
1. 登录认证
方式一:浏览器认证(推荐)
# 浏览器认证登录
quark auth
# 或指定配置文件路径
quark -c my-config.json auth这将打开浏览器窗口,请手动登录夸克网盘,工具会自动提取 Cookie。
方式二:手动配置
在项目根目录创建 config.json:
{
"Quark": {
"access_tokens": [
"__pus=your_cookie_value_here;"
]
}
}如何获取 Cookie:
- 在浏览器中登录 https://pan.quark.cn
- 打开开发者工具(F12)→ Application → Cookies
- 找到
__pusCookie 并复制值
2. 基本使用
# 获取用户信息
quark user
# 列出根目录
quark list "/"
# 流式输出(用于管道)
quark list "/" --stream
# 获取文件信息
quark info "/documents/file.txt"
# 下载文件
quark download "/documents/file.txt"
# 上传文件
quark upload "./local-file.txt" "/remote-file.txt"
# 创建文件夹
quark create "newfolder" "/"
# 移动文件
quark move "/old-path/file.txt" "/new-path/"
# 复制文件
quark copy "/file.txt" "/backup/"
# 重命名文件
quark rename "/oldname.txt" "newname.txt"
# 删除文件
quark delete "/file.txt"3. 分享操作
# 创建分享链接(7天,无提取码)
quark share "/file.txt" 7 "false"
# 创建带提取码的分享
quark share "/file.txt" 7 "true"
# 列出我的分享
quark share-list
# 通过 ID 删除分享
quark share-delete "share_id_here"
# 转存分享
quark share-save "https://pan.quark.cn/s/xxxxx" "passcode" "/destination/"4. 管道模式
# 列出文件并删除
quark list "/photos" --stream | quark delete
# 获取所有文件的下载链接
quark list "/documents" --stream | quark download
# 使用 jq 过滤
quark list "/" --stream | jq 'select(.size > 1000000)' | quark delete命令详解
全局选项
| 选项 | 说明 |
|------|------|
| -c, --config <path> | 配置文件路径(默认: config.json) |
| --cookies <value> | Cookie 值(跳过配置文件) |
| -v, --version | 显示版本号 |
| -h, --help | 显示帮助信息 |
命令列表
| 命令 | 说明 |
|---------|------|
| auth | 浏览器认证登录 |
| user | 获取用户信息 |
| list [path] | 列出目录内容 |
| info <path> | 获取文件/文件夹信息 |
| download <path> | 获取下载链接 |
| upload <file> <dest> | 上传文件 |
| create <name> <pdir> | 创建文件夹 |
| move <src> <dest> | 移动文件/文件夹 |
| copy <src> <dest> | 复制文件/文件夹 |
| rename <path> <newName> | 重命名文件/文件夹 |
| delete <path> | 删除文件/文件夹 |
| share <path> <days> <passcode> | 创建分享(days: 0=永久, 1/7/30) |
| share-delete <ids...> | 删除分享 |
| share-list | 列出我的分享 |
| share-save <url> [passcode] [dest] | 转存分享 |
输出格式
所有命令输出 JSON 格式到 stdout,方便解析:
成功:
{
"success": true,
"code": "OK",
"message": "操作成功",
"data": { }
}错误:
{
"success": false,
"code": "ERROR_CODE",
"message": "错误描述"
}服务端使用
SDK 可在服务端应用程序中程序化使用。所有 CLI 操作都可通过 SDK 模块调用。
⚠️ 部署前准备
部署到服务器前,你必须:
- 在本地运行
quark auth完成认证并生成config.json- 将
config.json复制到服务器部署目录,或者- 提取
__pusCookie 并设置为QUARK_COOKIE环境变量Cookie 会定期过期。建议实现健康检查来检测认证失败并提醒你重新认证。
基础 SDK 用法
import { QuarkClient, listFiles, getDownloadLink } from 'ali-quark-drive/sdk';
// 使用配置文件初始化客户端
const client = new QuarkClient('config.json');
await client.init();
// 或直接使用 Cookie 初始化
const client = new QuarkClient(undefined, '__pus=your_cookie;');
// 定期刷新认证(建议每4小时)
setInterval(async () => {
try {
await client.checkAuth();
console.log('认证刷新成功');
} catch (error) {
console.error('认证刷新失败:', error);
// 提醒管理员重新认证
}
}, 4 * 60 * 60 * 1000);
// 列出文件
const result = await listFiles(client, '/');
console.log(result.data?.files);
// 获取下载链接
const download = await getDownloadLink(client, '/file.txt');
console.log(download.data?.download_url);Express 示例
import express from 'express';
import { QuarkClient, listFiles, getDownloadLink, uploadFile } from 'ali-quark-drive/sdk';
const app = express();
app.use(express.json());
// 初始化客户端(单例模式)
let client: QuarkClient;
let authHealthy = false;
async function getClient() {
if (!client) {
client = new QuarkClient('config.json');
await client.init();
}
return client;
}
// 定期刷新认证
async function refreshAuth() {
try {
const quark = await getClient();
await quark.checkAuth();
authHealthy = true;
console.log('[认证] 刷新成功');
} catch (error) {
authHealthy = false;
console.error('[认证] 刷新失败:', error);
// TODO: 发送告警给管理员(邮件、Slack 等)
}
}
// 初始认证检查和定期刷新
getClient().then(() => refreshAuth());
setInterval(refreshAuth, 4 * 60 * 60 * 1000); // 每4小时
// 健康检查接口
app.get('/health', async (req, res) => {
if (!authHealthy) {
return res.status(503).json({
status: 'unhealthy',
reason: '认证已过期,请重新认证'
});
}
res.json({ status: 'healthy' });
});
// 认证错误处理辅助函数
function handleAuthError(error: unknown) {
const message = (error as Error).message;
if (message.includes('Authentication') || message.includes('cookie') || message.includes('认证')) {
authHealthy = false;
return { error: '认证已过期', code: 'AUTH_EXPIRED' };
}
return { error: message };
}
// 列出文件接口
app.get('/api/files/*', async (req, res) => {
try {
const path = '/' + req.params[0];
const quark = await getClient();
const result = await listFiles(quark, path);
if (!result.success && result.message?.includes('Authentication')) {
authHealthy = false;
return res.status(401).json({
error: '认证已过期',
code: 'AUTH_EXPIRED',
message: '请运行 quark auth 重新认证'
});
}
res.json(result);
} catch (error) {
res.status(500).json(handleAuthError(error));
}
});
// 获取下载链接接口
app.get('/api/download/*', async (req, res) => {
try {
const path = '/' + req.params[0];
const quark = await getClient();
const result = await getDownloadLink(quark, path);
res.json(result);
} catch (error) {
res.status(500).json(handleAuthError(error));
}
});
// 上传文件接口
app.post('/api/upload', async (req, res) => {
try {
const { localPath, remotePath } = req.body;
const quark = await getClient();
const result = await uploadFile(quark, localPath, remotePath);
res.json(result);
} catch (error) {
res.status(500).json(handleAuthError(error));
}
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});Koa 示例
import Koa from 'koa';
import Router from '@koa/router';
import bodyParser from 'koa-bodyparser';
import { QuarkClient, listFiles, getDownloadLink, createFolder } from 'ali-quark-drive/sdk';
const app = new Koa();
const router = new Router();
// 初始化客户端
let client: QuarkClient;
let authHealthy = false;
async function getClient() {
if (!client) {
client = new QuarkClient('config.json');
await client.init();
}
return client;
}
// 定期刷新认证
async function refreshAuth() {
try {
const quark = await getClient();
await quark.checkAuth();
authHealthy = true;
console.log('[认证] 刷新成功');
} catch (error) {
authHealthy = false;
console.error('[认证] 刷新失败:', error);
}
}
getClient().then(() => refreshAuth());
setInterval(refreshAuth, 4 * 60 * 60 * 1000);
// 带认证检测的错误处理中间件
app.use(async (ctx, next) => {
try {
await next();
} catch (error) {
const message = (error as Error).message;
if (message.includes('Authentication') || message.includes('cookie') || message.includes('认证')) {
authHealthy = false;
ctx.status = 401;
ctx.body = {
error: '认证已过期',
code: 'AUTH_EXPIRED',
message: '请运行 quark auth 重新认证'
};
} else {
ctx.status = 500;
ctx.body = { error: message };
}
}
});
app.use(bodyParser());
// 健康检查接口
router.get('/health', async (ctx) => {
if (!authHealthy) {
ctx.status = 503;
ctx.body = {
status: 'unhealthy',
reason: '认证已过期,请重新认证'
};
return;
}
ctx.body = { status: 'healthy' };
});
// 列出文件
router.get('/api/files/:path(.*)', async (ctx) => {
const path = '/' + (ctx.params.path || '');
const quark = await getClient();
const result = await listFiles(quark, path);
if (!result.success && result.message?.includes('Authentication')) {
authHealthy = false;
ctx.status = 401;
ctx.body = {
error: '认证已过期',
code: 'AUTH_EXPIRED'
};
return;
}
ctx.body = result;
});
// 创建文件夹
router.post('/api/folders', async (ctx) => {
const { name, parentDir = '/' } = ctx.request.body;
const quark = await getClient();
ctx.body = await createFolder(quark, name, parentDir);
});
// 获取下载链接
router.get('/api/download/:path(.*)', async (ctx) => {
const path = '/' + ctx.params.path;
const quark = await getClient();
ctx.body = await getDownloadLink(quark, path);
});
app.use(router.routes());
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});服务端环境变量
// 使用环境变量配置
const client = new QuarkClient(
process.env.QUARK_CONFIG_PATH,
process.env.QUARK_COOKIE
);可用 SDK 函数
| 函数 | 说明 |
|------|------|
| new QuarkClient(configPath?, cookies?) | 创建客户端实例 |
| client.init() | 异步初始化(使用配置文件时必需) |
| listFiles(client, path) | 列出目录内容 |
| getFileInfo(client, path) | 获取文件/文件夹详情 |
| getDownloadLink(client, path) | 获取文件下载 URL |
| uploadFile(client, localPath, remotePath) | 上传文件 |
| createFolder(client, name, parentDir) | 创建文件夹 |
| moveFile(client, src, dest) | 移动文件/文件夹 |
| copyFile(client, src, dest) | 复制文件/文件夹 |
| renameFile(client, path, newName) | 重命名文件/文件夹 |
| deleteFile(client, path) | 删除文件/文件夹 |
| createShare(client, path, days, passcode) | 创建分享链接 |
| deleteShare(client, shareId) | 删除分享 |
| listShares(client, options) | 列出我的分享 |
| saveShare(client, url, passcode?, destDir?) | 转存分享到网盘 |
开发
开发使用
开发或修改源代码时,直接使用 node dist/cli.js:
# 构建后
node dist/cli.js auth
node dist/cli.js user
node dist/cli.js list "/"脚本命令
# 编译 TypeScript
npm run build
# 监听模式编译
npm run dev
# 运行测试
npm run test
# 监听模式运行测试
npm run test:watch
# 运行测试并生成覆盖率报告
npm run test:coverage
# 类型检查(不输出文件)
npm run lint项目结构
ali-quark-drive/
├── bin/ # 命令行包装脚本
│ ├── quark # Unix shell 脚本
│ └── quark.cmd # Windows batch 脚本
├── src/ # 源代码
│ ├── cli.ts # CLI 入口
│ ├── auth.ts # 浏览器认证
│ ├── __tests__/ # 测试文件
│ └── sdk/ # SDK 模块
│ ├── index.ts # SDK 导出
│ ├── client.ts # QuarkClient 类
│ ├── config.ts # 配置管理
│ ├── constants.ts # API 端点
│ ├── types.ts # TypeScript 类型
│ ├── files.ts # 文件操作
│ └── share.ts # 分享操作
├── dist/ # 编译输出 (gitignored)
├── coverage/ # 测试覆盖率报告 (gitignored)
├── jest.config.mjs # Jest 配置
├── tsconfig.json # TypeScript 配置
└── package.json # 项目配置测试
# 运行所有测试
npm run test
# 运行特定测试文件
npm run test -- config.test.ts
# 生成 HTML 覆盖率报告
npm run test:coverage
# 报告位于 coverage/index.html环境变量
| 变量 | 说明 |
|----------|------|
| QUARK_DEBUG | 设置为 1 启用调试日志 |
| QUARK_COOKIE | Cookie 字符串(替代配置文件) |
| QUARK_PATH | CLI 完整路径(用于 OpenClaw) |
故障排除
常见问题
1. 配置文件未找到
# 手动创建配置
quark auth
# 或
echo '{"Quark":{"access_tokens":["__pus=your_cookie;"]}}' > config.json2. 认证失败
- 检查 Cookie 是否过期
- 重新运行
auth命令刷新
3. 命令未找到(本地安装) 请确保使用以下方式之一:
# 使用 npx
npx quark <命令>
# 或在 package.json 中添加 scripts 后通过 npm run 运行4. 测试失败(开发)
# 清理安装
rm -rf node_modules coverage dist
npm install
npm run build
npm test许可证
本项目采用 专有许可证 发布。源码可见,但 不是开源软件。商用使用仅在 LICENSE 文件约定范围内被允许。
免责声明
这是一个非官方的夸克网盘第三方工具。它与夸克没有任何关联,不受夸克认可或赞助。使用风险自负。作者不对因使用本工具导致的任何数据丢失、账号封禁或其他损害负责。
本项目仅供学术研究、互操作性测试、学习交流及其他合法用途。你有责任自行确认你的使用行为符合适用法律、平台条款及第三方权利要求。严禁将本项目用于非法用途、未授权操作、规避限制、滥用自动化或侵权行为。
本文档中的示例仅用于演示说明。在执行批量化、自动化或商业化流程前,请先自行确认相关法律要求、平台条款以及你的授权状态。
致谢
构建工具:TypeScript、Commander.js、Playwright
