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

picgo-plugin-s3-uploader

v1.0.1

Published

S3-compatible PicGo uploader that emits imgproxy-friendly source metadata.

Readme

picgo-plugin-s3-uploader

一个面向 AWS S3、Garage、MinIO 等 S3 兼容对象存储的 PicGo 插件,支持文件上传、删除,以及输出 imgproxy 等插件使用的数据字段

它负责把文件上传到 S3 兼容服务,并输出:

  • 正常可访问的 url / imgUrl
  • picgo-plugin-imgproxy 使用的稳定 imgproxySource

功能概览

  • 支持 AWS S3 / Garage / MinIO 等 S3 兼容服务
  • 支持 PicGo GUI 删除文件时同步执行 S3 DELETE Object
  • 支持 uploadPath 上传路径模板
  • 支持 outputURLPattern 自定义输出 URL 模板
  • 常见图片、视频、音频、文档、压缩包、网页资源类型会自动写入合适的 Content-Type
  • 可选写入 Content-Disposition: inline,让浏览器更倾向于直接预览
  • 内置中英文文案,并优先跟随 PicGo / PicList 当前语言设置

安装

PicGo GUI / PicList

  • 可以直接在插件设置页安装 s3-uploader
  • 也可以安装完整包名 picgo-plugin-s3-uploader

PicGo Core

picgo install picgo-plugin-s3-uploader

配置项

| Key | 说明 | 示例 | | --- | --- | --- | | accessKeyID | S3 Access Key。 | YOUR_ACCESS_KEY | | secretAccessKey | S3 Secret Key。 | YOUR_SECRET_KEY | | bucketName | 目标 bucket 名称。 | public | | uploadPath | 上传路径模板,可使用占位符。 | img/{year}/{month}/{md5}.{ext} | | outputURLPattern | 自定义输出 URL 模板;为空时按默认规则推导公开 URL。 | https://cdn.example.com/{encodedKey} | | region | 签名区域。AWS 常见为 us-east-1;Garage 为 garage。 | us-east-1 | | endpoint | S3 API Endpoint。AWS S3 可留空。必须是完整的 http://https:// 地址。 | https://minio.example.com | | pathStyleAccess | 是否使用 path-style 请求。Garage / MinIO 常见为 true。 | true | | rejectUnauthorized | 是否拒绝无效 TLS 证书。 | true | | acl | 对象 ACL;若服务不支持可留空。 | public-read | | contentDispositionInline | 是否在上传时写入 Content-Disposition: inline。 | false |

配置示例

Garage

{
  "picBed": {
    "current": "s3-uploader",
    "uploader": "s3-uploader",
    "s3-uploader": {
      "accessKeyID": "YOUR_ACCESS_KEY",
      "secretAccessKey": "YOUR_SECRET_KEY",
      "bucketName": "public",
      "uploadPath": "img/{year}/{month}/{md5}.{ext}",
      "outputURLPattern": "https://{bucket}.example.com/{encodedKey}",
      "region": "garage",
      "endpoint": "https://garage-api.example.com",
      "pathStyleAccess": true,
      "rejectUnauthorized": true,
      "acl": "public-read",
      "contentDispositionInline": true
    }
  }
}

MinIO

{
  "picBed": {
    "current": "s3-uploader",
    "uploader": "s3-uploader",
    "s3-uploader": {
      "accessKeyID": "YOUR_ACCESS_KEY",
      "secretAccessKey": "YOUR_SECRET_KEY",
      "bucketName": "public",
      "uploadPath": "img/{year}/{month}/{fileName:/\\s+/g,'-'}.{extName}",
      "outputURLPattern": "https://cdn.example.com/{encodedKey}",
      "region": "us-east-1",
      "endpoint": "https://minio.example.com",
      "pathStyleAccess": true,
      "rejectUnauthorized": true,
      "acl": "public-read",
      "contentDispositionInline": true
    }
  }
}

AWS S3

{
  "picBed": {
    "current": "s3-uploader",
    "uploader": "s3-uploader",
    "s3-uploader": {
      "accessKeyID": "YOUR_ACCESS_KEY",
      "secretAccessKey": "YOUR_SECRET_KEY",
      "bucketName": "public",
      "uploadPath": "img/{year}/{month}/{uuidN}.{extName}",
      "outputURLPattern": "https://cdn.example.com/{encodedKey}",
      "region": "us-east-1",
      "pathStyleAccess": false,
      "rejectUnauthorized": true,
      "acl": "public-read",
      "contentDispositionInline": true
    }
  }
}

预览与下载

浏览器是“直接预览”还是“弹出下载”,主要取决于对象响应头:

  • Content-Type 是否正确,例如 video/mp4application/pdf
  • Content-Disposition 是否被设置为 attachmentinline

本插件默认不会强行写 Content-Disposition,而是优先依赖正确的 Content-Type。如果你希望浏览器更明确地按预览处理,可以开启 contentDispositionInline

模板语法

uploadPathoutputURLPattern 共用同一套模板语法。

通用占位符

以下占位符在 uploadPathoutputURLPattern 中都可使用。

| 分类 | 占位符 | | --- | --- | | 时间 | {year} {month} {day} {hour} {minute} {second} {millisecond} {timestamp} {timestampMS} | | 文件 | {fullName} {fileName} {filename} {basename} {name} {extName} {ext} | | 哈希 | {crc32} {md5} {md5B64} {md5B64Short} {sha1} {sha256} | | 上传上下文 | {bucket} {region} {acl} {contentType} {mime} {size} {uuid} {uuidN} | | Endpoint | {endpoint} {endpointOrigin} {endpointProtocol} {endpointHost} {endpointHostname} {endpointPort} {endpointPath} {pathStyleAccess} |

outputURLPattern 专属占位符

| 占位符 | 说明 | | --- | --- | | {url} | 插件按默认规则推导出的公开 URL | | {origin} {protocol} {host} {hostname} {port} | 默认公开 URL 的主机信息 | | {pathname} | 默认公开 URL 的路径部分,带前导 / | | {path} | 默认公开 URL 的路径部分,不带前导 / | | {key} {objectKey} {uploadPath} | 对象 key,未编码 | | {encodedKey} | URL 安全的对象 key | | {dir} | 对象 key 的目录部分,未编码 | | {encodedDir} | URL 安全的目录部分 | | {bucketPath} | bucket/key | | {encodedBucketPath} | URL 安全的 bucket/key | | {eTag} {etag} | 上传返回的 eTag |

模板操作语法

下面用一组固定输入说明模板操作语法:

| 字段 | 示例值 | | --- | --- | | bucket | public-bucket | | md5 | 2095312189753de6ad47dfe20cbe97ec | | fileName | Echo idle 01 | | fullName | Echo idle 01.png |

| 写法 | 输入 | 结果 | 说明 | | --- | --- | --- | --- | | {bucket} | bucket = public-bucket | public-bucket | 直接取值 | | {md5:8} | md5 = 2095312189753de6ad47dfe20cbe97ec | 20953121 | 取前 8 位 | | {md5:0,8} | md5 = 2095312189753de6ad47dfe20cbe97ec | 20953121 | 从第 0 位开始取 8 位 | | {fileName:/\\s+/g,'-'} | fileName = Echo idle 01 | Echo-idle-01 | 把连续空格替换为 - | | {fullName:/\\s+/g,'_'} | fullName = Echo idle 01.png | Echo_idle_01.png | 把连续空格替换为 _ | | {fullName:/[^A-Za-z0-9._-]+/g,''} | fullName = Echo idle 01.png | Echoidle01.png | 移除空格和其他不在白名单内的字符 |

说明:

  • {name:8} 等价于 {name:0,8}
  • 正则写法中的 flags 可省略
  • replacement 需要写在单引号里

常见模板示例

| 场景 | 模板 | 结果示例 | | --- | --- | --- | | 按年月归档 | img/{year}/{month}/{fullName} | img/2026/03/Echo idle 01.png | | 用 md5 作为文件名 | img/{year}/{month}/{md5}.{ext} | img/2026/03/2095312189753de6ad47dfe20cbe97ec.png | | 把空格替换为 - | img/{fileName:/\\s+/g,'-'}.{extName} | img/Echo-idle-01.png | | 输出到 CDN | https://cdn.example.com/{encodedKey} | https://cdn.example.com/img/Echo-idle-01.png | | bucket 作为子域名 | https://{bucket}.cdn.example.com/{encodedKey} | https://public.cdn.example.com/img/Echo-idle-01.png |

outputURLPattern 使用建议

如果你是在拼装最终公开 URL,优先使用:

| 推荐占位符 | 原因 | | --- | --- | | {encodedKey} | 对中文、空格和特殊字符更安全 | | {path} / {pathname} | 可以直接复用默认推导出的路径结构 | | {encodedBucketPath} | 适合自行拼接 bucket/key |

endpoint 规则

| 项目 | 说明 | | --- | --- | | 填写内容 | endpoint 填的是 S3 API 地址,不是 CDN 域名或公开访问域名 | | AWS S3 | 可留空,插件会根据 region 自动推导 | | 协议要求 | 必须写完整的 http://https:// | | 禁止内容 | 不允许带 query / hash | | 域名分离场景 | 如果公开访问域名和 API 地址不同,请把公开域名写到 outputURLPattern | | 自动归一化 | 若误把 bucket 写进 endpoint 的 host 或 path,插件会自动去重 |

默认公开 URL 推导规则

outputURLPattern 为空时:

| 条件 | 结果 | | --- | --- | | endpoint 已设置,pathStyleAccess = true | https://endpoint/bucket/key | | endpoint 已设置,pathStyleAccess = false | https://bucket.endpoint/key | | endpoint 未设置 | 按 AWS 官方 S3 域名规则结合 region 自动推导 |

如果你的 API Endpoint、公开访问域名、CDN 域名不是同一个地址,建议显式配置 outputURLPattern

上传成功后写入的字段

这些字段可供其他插件继续消费,尤其是 picgo-plugin-imgproxy

| 字段 | 说明 | 示例 | | --- | --- | --- | | uploadPath | 对象 key | img/Echo-idle-01.png | | eTag | 上传返回的 eTag | etag-value | | imgproxySource.backend | 固定为 s3 | s3 | | imgproxySource.bucket | bucket 名称 | public | | imgproxySource.key | 对象 key | img/Echo-idle-01.png |

对应的 S3 来源统一为:

s3://bucket/key

删除支持

PicGo GUI 删除文件时,本插件会监听 remove 事件,并对当前插件上传的对象执行 S3 DELETE Object

| 行为 | 说明 | | --- | --- | | 删除范围 | 只处理 type === "s3-uploader" 的项目 | | key 来源 | 优先使用 imgproxySource.key,没有时回退到 uploadPath | | 不存在对象 | 记为“已不存在”,不视为硬错误 | | 用户反馈 | 会同时写日志,并在 GUI 中弹出通知 |

与 picgo-plugin-imgproxy 联用

当你同时安装:

  • picgo-plugin-s3-uploader
  • picgo-plugin-imgproxy

并在 picgo-plugin-imgproxy 中开启:

{
  "enableS3Source": true
}

imgproxy 插件会优先读取本插件写出的:

{
  "imgproxySource": {
    "backend": "s3",
    "bucket": "public",
    "key": "img/Echo-idle-01.png"
  }
}

并据此生成s3格式的链接进行处理:

/rs:fit:300:300/plain/s3://public/img/Echo-idle-01.png