npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

xin_oss-upload

v1.0.0

Published

上传到oss的工具

Downloads

104

Readme

@xin/oss-upload

多厂商 OSS 文件上传工具库,支持阿里云 OSS、腾讯云 COS、七牛云,提供统一的 API 接口。

安装

pnpm add @xin/oss-upload

快速开始

工厂函数(推荐)

使用 createOSSUploader 根据配置自动创建对应厂商的上传器:

import { createOSSUploader } from '@xin/oss-upload'

const uploader = createOSSUploader({
  vendor: 'aliyun',
  region: 'oss-cn-hangzhou',
  accessKeyId: 'YOUR_ACCESS_KEY_ID',
  accessKeySecret: 'YOUR_ACCESS_KEY_SECRET',
  bucket: 'your-bucket',
})

const result = await uploader.uploadFile('/path/to/local/file.jpg', {
  targetPath: 'images/file.jpg',
})

console.log(result.url)     // 访问 URL
console.log(result.size)    // 文件大小(字节)
console.log(result.costTime) // 上传耗时(ms)

直接实例化

import { AliyunOSSUploader } from '@xin/oss-upload'

const uploader = new AliyunOSSUploader({ ... })

配置项

通用配置(所有厂商)

| 字段 | 类型 | 必填 | 说明 | | -------------- | --------- | ---- | ------------------------- | | vendor | string | ✅ | 厂商标识,见下方各厂商配置 | | secure | boolean | — | 是否使用 HTTPS,默认 true | | customDomain | string | — | 自定义 CDN 域名(不含协议)|

阿里云 OSS — vendor: 'aliyun'

import { createOSSUploader } from '@xin/oss-upload'

const uploader = createOSSUploader({
  vendor: 'aliyun',
  region: 'oss-cn-hangzhou',         // OSS 地域
  accessKeyId: 'YOUR_KEY_ID',
  accessKeySecret: 'YOUR_KEY_SECRET',
  bucket: 'your-bucket',
  endpoint: 'oss-cn-hangzhou.aliyuncs.com', // 可选,自定义 Endpoint
  customDomain: 'cdn.example.com',   // 可选,自定义域名
})

| 字段 | 类型 | 必填 | 说明 | | ----------------- | -------- | ---- | ----------------- | | region | string | ✅ | OSS 地域 | | accessKeyId | string | ✅ | AccessKey ID | | accessKeySecret | string | ✅ | AccessKey Secret | | bucket | string | ✅ | 存储空间名称 | | endpoint | string | — | 自定义 Endpoint |

腾讯云 COS — vendor: 'tencent'

const uploader = createOSSUploader({
  vendor: 'tencent',
  region: 'ap-guangzhou',   // COS 地域
  secretId: 'YOUR_SECRET_ID',
  secretKey: 'YOUR_SECRET_KEY',
  bucket: 'your-bucket',    // 不含 AppId 的桶名
  appId: '1250000000',      // 腾讯云 AppId
  customDomain: 'cdn.example.com', // 可选
})

完整存储桶名称由 bucket-appId 拼接,SDK 内部自动处理。

| 字段 | 类型 | 必填 | 说明 | | ----------- | -------- | ---- | ----------------- | | region | string | ✅ | COS 地域 | | secretId | string | ✅ | SecretId | | secretKey | string | ✅ | SecretKey | | bucket | string | ✅ | 存储桶名(不含 AppId)| | appId | string | ✅ | 腾讯云 AppId |

七牛云 — vendor: 'qiniu'

const uploader = createOSSUploader({
  vendor: 'qiniu',
  zone: 'z0',               // 存储区域
  accessKey: 'YOUR_ACCESS_KEY',
  secretKey: 'YOUR_SECRET_KEY',
  bucket: 'your-bucket',
  domain: 'cdn.example.com', // 空间绑定的域名(必填)
})

| 字段 | 类型 | 必填 | 说明 | | ----------- | -------- | ---- | --------------------- | | zone | string | ✅ | 存储区域,见下方枚举 | | accessKey | string | ✅ | AccessKey | | secretKey | string | ✅ | SecretKey | | bucket | string | ✅ | 存储空间名称 | | domain | string | ✅ | 空间绑定的访问域名 |

zone 枚举值:

| 值 | 区域 | | ----- | ------ | | z0 | 华东 | | z1 | 华北 | | z2 | 华南 | | na0 | 北美 | | as0 | 东南亚 |


上传选项 UploadOptions

await uploader.uploadFile('/local/path/file.jpg', {
  targetPath: 'images/2024/file.jpg', // 必填,OSS 上的目标路径
  overwrite: false,                   // 是否覆盖同名文件,默认 false
  timeout: 60000,                     // 超时时间(ms),默认 60000
  partSize: 10 * 1024 * 1024,        // 分片大小(字节),默认 10MB
  parallel: 5,                        // 分片并发数,默认 5
  onProgress: (percent) => {          // 进度回调,0-100
    console.log(`上传进度: ${percent}%`)
  },
})

| 字段 | 类型 | 必填 | 默认值 | 说明 | | ------------ | ----------------------------- | ---- | -------- | -------------- | | targetPath | string | ✅ | — | OSS 目标路径 | | overwrite | boolean | — | false | 是否覆盖已有文件 | | timeout | number | — | 60000 | 超时(ms) | | partSize | number | — | 10MB | 分片大小 | | parallel | number | — | 5 | 分片并发数 | | onProgress | (percent: number) => void | — | — | 进度回调(0-100)|


上传结果 UploadResult

interface UploadResult {
  url: string      // 文件访问 URL
  path: string     // OSS 上的存储路径
  size: number     // 文件大小(字节)
  costTime: number // 上传耗时(ms)
  md5?: string     // 文件 MD5(部分厂商提供)
}

方法

所有上传器均继承自 BaseOSSUploader,提供以下方法:

uploadFile(filePath, options)

上传本地文件到 OSS。

const result = await uploader.uploadFile('/local/file.jpg', {
  targetPath: 'uploads/file.jpg',
})

deleteFile(objectName)

删除 OSS 上的文件,文件不存在时也返回 true

const success = await uploader.deleteFile('uploads/file.jpg')

getFileUrl(objectName)

获取文件的访问 URL(不包含签名,适用于公开读 Bucket)。

const url = uploader.getFileUrl('uploads/file.jpg')

destroy()

释放客户端资源。

uploader.destroy()

错误处理

所有错误均以 OSSUploadError 抛出:

import { OSSUploadError } from '@xin/oss-upload'

try {
  await uploader.uploadFile('/path/to/file.jpg', {
    targetPath: 'images/file.jpg',
  })
} catch (err) {
  if (err instanceof OSSUploadError) {
    console.error('错误信息:', err.message)
    console.error('错误码:', err.code)
    console.error('请求 ID:', err.requestId)
  }
}

常见错误码:

| code | 说明 | | ----------------------- | ------------------------ | | INVALID_CONFIG | 配置项缺失或非法 | | CLIENT_INIT_FAILED | SDK 客户端初始化失败 | | CLIENT_NOT_INIT | 客户端未初始化(已销毁) | | NOT_A_FILE | 指定路径不是文件 | | FILE_EXISTS | 文件已存在且未开启覆盖 | | CHECK_FILE_FAILED | 检查文件存在性失败 | | UPLOAD_FAILED | 上传失败 | | DELETE_FAILED | 删除失败 |


完整示例

import { createOSSUploader, OSSUploadError } from '@xin/oss-upload'

// 1. 创建上传器
const uploader = createOSSUploader({
  vendor: 'tencent',
  region: 'ap-guangzhou',
  secretId: process.env.COS_SECRET_ID!,
  secretKey: process.env.COS_SECRET_KEY!,
  bucket: 'my-bucket',
  appId: '1250000000',
  customDomain: 'cdn.example.com',
})

// 2. 上传文件
try {
  const result = await uploader.uploadFile('./avatar.png', {
    targetPath: `avatars/${Date.now()}.png`,
    overwrite: false,
    onProgress: (p) => console.log(`${p}%`),
  })
  console.log('上传成功:', result.url)
} catch (err) {
  if (err instanceof OSSUploadError) {
    console.error(`[${err.code}] ${err.message}`)
  }
}

// 3. 删除文件
await uploader.deleteFile('avatars/old.png')

// 4. 释放资源
uploader.destroy()

开发

pnpm install      # 安装依赖
pnpm test         # 运行测试
pnpm test:watch   # 监听模式
pnpm build        # 构建发布产物