{"_id":"@aim-packages/downloader","_rev":"2-29873fc453946c856ad418303f2d1137","name":"@aim-packages/downloader","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@aim-packages/downloader","version":"0.1.0","keywords":["downloader","file-download","resume-download","proxy","retry"],"author":{"name":"Yu","email":"yuqian.124@gmail.com"},"license":"MIT","_id":"@aim-packages/downloader@0.1.0","maintainers":[{"name":"moyufed","email":"yuqian.124@gmail.com"}],"dist":{"shasum":"2b8d6a22bea0ec7f4db8db268ef34f3268dbb50e","tarball":"https://registry.npmjs.org/@aim-packages/downloader/-/downloader-0.1.0.tgz","fileCount":5,"integrity":"sha512-Tm1ksm7ebY66h4DG2F7Myls44tE1RRoWhvGdP7N7LfH+oUTF96id7OHhWcMVQq74OlXMxbzq3yG1vb50+mwx5Q==","signatures":[{"sig":"MEUCIBsos99oRGxuV8KRnKOai3UnTIKjULosPEj3EtY39fQwAiEA3QbiVbHdTsQih9rsEB9AKq5jR1WoaxoxB/q8NBdFGIE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":64070},"main":"dist/index.cjs.js","type":"module","types":"dist/index.d.ts","module":"dist/index.es.js","gitHead":"7435ac40929cbf9335a58fec4be5127dc5a657b1","scripts":{"dev":"vite","build":"tsc && vite build","preview":"vite preview","release":"pnpm build && npm publish --registry=https://registry.npmjs.org/ --access public"},"_npmUser":{"name":"moyufed","email":"yuqian.124@gmail.com"},"_npmVersion":"9.6.7","description":"基于 node-downloader-helper 的下载器，支持断点续传、自动重试、代理等特性","directories":{},"_nodeVersion":"18.17.1","dependencies":{"node-downloader-helper":"^2.1.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.0.5","typescript":"~5.6.2","@types/node":"^24.2.0","vite-plugin-dts":"^4.5.0"},"_npmOperationalInternal":{"tmp":"tmp/downloader_0.1.0_1768209845434_0.9531615449248201","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aim-packages/downloader","version":"0.2.0","type":"module","description":"基于 node-downloader-helper 的下载器，支持断点续传、自动重试、代理等特性","main":"dist/index.cjs.js","module":"dist/index.es.js","types":"dist/index.d.ts","scripts":{"dev":"vite","build":"tsc && vite build","preview":"vite preview","release":"pnpm build && npm publish --registry=https://registry.npmjs.org/ --access public"},"keywords":["downloader","file-download","resume-download","proxy","retry"],"author":{"name":"Yu","email":"yuqian.124@gmail.com"},"license":"MIT","dependencies":{"node-downloader-helper":"^2.1.9"},"devDependencies":{"@types/node":"^24.2.0","typescript":"~5.6.2","vite":"^6.0.5","vite-plugin-dts":"^4.5.0"},"publishConfig":{"access":"public"},"gitHead":"b78a98ab82edc7d487410a0711ab209e5ab1ef73","_id":"@aim-packages/downloader@0.2.0","_nodeVersion":"18.17.1","_npmVersion":"9.6.7","dist":{"integrity":"sha512-OjgZ3XDrniHPIDjK3bkkp6fqiJ/TdLm4k8szIjN+fGj7v4lrPhhVZdkKvgqBaGO3oHYsyZGthL/FmLqCW3negQ==","shasum":"45cd1d462e5b6627fe5b76c3665b0e59e3d774bf","tarball":"https://registry.npmjs.org/@aim-packages/downloader/-/downloader-0.2.0.tgz","fileCount":5,"unpackedSize":78903,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCxdFj8TSF6/kmPfTqTCfnExTEXxsxU2ruGvWNstJAlDgIhAJDlVmkzElqGWPhzbpriLAYAJTESVDJqBih8icc/0MrU"}]},"_npmUser":{"name":"moyufed","email":"yuqian.124@gmail.com"},"directories":{},"maintainers":[{"name":"moyufed","email":"yuqian.124@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/downloader_0.2.0_1778571407736_0.009156509864583384"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-12T09:24:05.360Z","modified":"2026-05-12T07:36:48.008Z","0.1.0":"2026-01-12T09:24:05.564Z","0.2.0":"2026-05-12T07:36:47.883Z"},"author":{"name":"Yu","email":"yuqian.124@gmail.com"},"license":"MIT","keywords":["downloader","file-download","resume-download","proxy","retry"],"description":"基于 node-downloader-helper 的下载器，支持断点续传、自动重试、代理等特性","maintainers":[{"name":"moyufed","email":"yuqian.124@gmail.com"}],"readme":"# @aim-packages/downloader\n\n由于在 electron 中没有找到好的下载库，以前使用过的 electron-dl 存在一些问题，代理设置也不方便，现在基于 [`node-downloader-helper`](https://github.com/hgouveia/node-downloader-helper) 的增强型 Node.js 文件下载库。\n\n## ✨ 额外功能\n\n本库在 `node-downloader-helper` 基础上提供了两个额外功能：\n\n1. **临时文件机制** - 下载过程中使用 `.download` 后缀的临时文件，下载完成并校验通过后才重命名为最终文件\n2. **SHA256 文件校验** - 下载完成后自动验证文件 SHA256 哈希值，确保文件完整性\n3. **可选续传校验** - 可在断点续传前通过 HEAD 校验远端资源是否仍是同一文件\n\n## 📦 安装\n\n```bash\npnpm add @aim-packages/downloader\n```\n\n## 🚀 快速开始\n\n```typescript\nimport { createDownloader } from '@aim-packages/downloader';\n\nconst downloader = createDownloader();\n\n// 基本下载\nconst filePath = await downloader.download(\n  'https://example.com/file.zip',\n  '/path/to/destination/file.zip'\n);\n\n// 带 SHA256 校验的下载\nawait downloader.download(\n  'https://example.com/file.zip',\n  '/path/to/destination/file.zip',\n  {\n    sha256: 'expected-sha256-hash-value'\n  }\n);\n\n// 开启续传前 HEAD 校验（默认关闭，以保持旧版本行为兼容）\nawait downloader.download(\n  'https://example.com/file.zip',\n  '/path/to/destination/file.zip',\n  {\n    resumeValidation: true,\n    debug: true\n  }\n);\n```\n\n## 💡 使用示例\n\n### 使用 AbortSignal 取消下载\n\n```typescript\nimport { createDownloader, DownloadCancelledError } from '@aim-packages/downloader';\n\nconst downloader = createDownloader();\nconst abortController = new AbortController();\n\n// 5 秒后取消下载\nsetTimeout(() => {\n  abortController.abort();\n}, 5000);\n\ntry {\n  await downloader.download(\n    'https://example.com/file.zip',\n    '/path/to/destination/file.zip',\n    {\n      signal: abortController.signal\n    }\n  );\n} catch (error) {\n  if (error instanceof DownloadCancelledError) {\n    console.log('下载已取消');\n  }\n}\n```\n\n### 使用代理下载\n\n```typescript\nimport { createDownloader } from '@aim-packages/downloader';\nimport { HttpsProxyAgent } from 'https-proxy-agent';\n\nconst downloader = createDownloader();\nconst proxyAgent = new HttpsProxyAgent('http://proxy.example.com:8080');\n\nawait downloader.download(\n  'https://example.com/file.zip',\n  '/path/to/destination/file.zip',\n  {\n    proxyAgent\n  }\n);\n```\n\n## 🔧 技术细节\n\n### 调试日志\n\n- 默认不打印内部下载日志，避免库在宿主项目里产生额外输出\n- 传入 `debug: true` 后会打印下载开始、续传校验、重试、失败等内部日志\n- 下载失败仍会通过 Promise reject 抛出，不依赖日志传递错误信息\n\n### 临时文件机制\n\n- 下载过程中使用 `.download` 后缀的临时文件（例如：`file.zip.download`）\n- 下载完成后进行 SHA256 校验（如果提供）\n- 校验通过后才重命名为最终文件（去掉 `.download` 后缀）\n- 校验失败自动删除文件并抛出 `HashMismatchError`\n\n### SHA256 校验\n\n- 如果提供了 `sha256` 选项，下载完成后会自动计算文件的 SHA256 哈希值\n- 如果哈希值不匹配，会抛出 `HashMismatchError` 并删除文件\n- 如果哈希值匹配，文件会重命名为最终文件名\n\n### 续传前 HEAD 校验\n\n默认情况下，本库保持旧版本行为：直接使用 `node-downloader-helper` 的 `resumeIfFileExists` 能力，不额外发送 HEAD 校验请求。\n\n如果传入 `resumeValidation: true`，下载器会：\n\n- 为临时文件维护元信息文件，默认路径为 `${destinationPath}.download.meta.json`\n- 首次开始下载前通过 HEAD 记录 `ETag`、`Last-Modified`、`Content-Length`、`Accept-Ranges`\n- 下次发现 `.download` 临时文件时，再次 HEAD 并比较远端资源标识\n- 只有强 ETag 或 Last-Modified 匹配，且默认要求 `Accept-Ranges: bytes` 时才继续续传\n- 如果资源标识缺失或不匹配，会删除旧 `.download` 和旧元信息，从头下载\n- 下载成功、重命名成功后会清理元信息\n- hash 校验失败、文件大小校验失败或重命名失败时，会删除临时文件和元信息\n\n也可以传入更细的配置：\n\n```typescript\nawait downloader.download(url, filePath, {\n  resumeValidation: {\n    enabled: true,\n    metadataPath: `${filePath}.resume.json`,\n    requireRangeSupport: true,\n    allowSizeOnlyResume: false,\n    headTimeoutMs: 30000\n  }\n});\n```\n\n## 📋 错误类型\n\n### `HashMismatchError`\n\nHash 校验失败错误。\n\n```typescript\nclass HashMismatchError extends Error {\n  constructor(\n    message?: string,\n    public readonly expected?: string,\n    public readonly actual?: string\n  );\n}\n```\n\n### `DownloadCancelledError`\n\n下载取消错误。当通过 `AbortSignal` 取消下载时抛出。\n\n```typescript\nclass DownloadCancelledError extends Error {\n  constructor(message?: string);\n}\n```\n","readmeFilename":"README.md"}