@focus-at/zs3

中文文档
0.1.0发布于 2026/11/07MITTypeScriptES Module零依赖近 30 天下载 4099

Zero-dependency 3 KB S3客户端基于WS,Edge,Cloudflare Workers,Bun,Node,和浏览器运行时间的Web标准而构建.

中文使用文档
文档目录11 节
  1. 概览
  2. 特征
  3. 快速启动
  4. 有用的操作模式
  5. 按页列出对象
  6. 处理对象版本
  7. 设定对象元数据和标签
  8. 发送自定义请求
  9. 将一个大对象按部件上传
  10. API 覆盖图
  11. 实例

ZS3 坐标

GitHub License npm version npm package minimized gzipped size no dependencies NPM Downloads

0 运行时间依赖性 ^ 只 ~ 3 KB 已修改 ^ 在 Web 平台 API 上构建

ZS3正在积极开发中;公共API可能会演化.

Tests GitHub Stars

概览

ZS3 坐标 是JavaScript和TypeScript的轻量级S3兼容客户端. 仅限 ~3 KB 已修改,它会签署 AWS 签名版本 4 请求,并通过标准 Web 平台 API 等与对象存储通信 fetch, (中文(简体) ), Response, (中文(简体) ), TextEncoder,以及 crypto.subtle。 。 。 .

使用 exec() 签署和发出请求,或 sign() 创建预先签名的 URL , 并定期发送 fetch()土著 Response 对象可以方便地流出下载,检查信头,并与网络框架相融合.

ZeroS3目标 Node.js, Bun, 浏览器, 以及 Cloudflare 工人等边缘运行时间,只要有所需的网络API.

特征

从包脚印和平台基础订购到S3能力:

  • 只有~3 KB 已修改 ——用于性能敏感应用的紧凑客户端.
  • 零依赖关系 ——建于原生的Web API上,没有SDK依赖树.
  • 类型脚本 ——打出配置,请求选项,客户端方法,以及S3响应形状. 公共类型: @focus-at/zs3/types。 。 。 .
  • 网络平台 API - 用途 fetch, (中文(简体) ), Response, (中文(简体) ), TextEncoder,以及 crypto.subtle。 。 。 .
  • 节点.js、 Bun、 浏览器和边缘运行时间 ——包括Cloudflare Workers,那里有所需的网络API.
  • S3 兼容 API ——用于桶操作,对象上市和平面图,对象CRUD,元数据,标记,和S3子资源的一致请求模型.
  • AWS 签名版本 4 ——签署直接请求或生成预先签名的URL.

快速启动

npm install @focus-at/zs3

在信任的服务器环境中生成一个短命的 URL, 然后让浏览器按照标准发送请求 fetch(),在服务器上保留永久证书;从不披露浏览器代码中的秘密访问密钥.

// Server: create a pre-signed URL.
import { zs3 } from "@focus-at/zs3";

const signer = zs3({
  endpoint: process.env.S3_ENDPOINT!,
  accessKeyId: process.env.S3_ACCESS_KEY_ID!,
  secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
  region: "us-east-1",
});

const url = await signer.sign(
  { method: "GET", bucket: "my-bucket", key: "reports/annual.pdf" },
  { expiresIn: 300 },
);

// Browser: use the URL with the standard Fetch API.
const response = await fetch(url);

console.log(response.status, await response.blob());

对于直接服务器侧请求, exec() 签名并发送请求并返回本地 Response数字 :

import { zs3 } from "@focus-at/zs3";
import type { ZS3Objects } from "@focus-at/zs3/types";

const client = zs3({
  endpoint: process.env.S3_ENDPOINT!,
  accessKeyId: process.env.S3_ACCESS_KEY_ID!,
  secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
  bucket: "my-bucket",
});

const response = await client.exec<ZS3Objects>({ method: "GET", prefix: "reports/" });

const { key, data }  = await response.json();

console.log(data);

自定义用户系统平滑

import { zs3, handler } from 'zs3-sdk';

const s3 = zs3({
  handler: async (res: Response) => {
    const { key, data } = await handler(res);
    return data; // Manual flattening on the user side if they don't need the root key
  }
});

有用的操作模式

按页列出对象

使用 fetch-owner 将所有者信息列入清单。 下一页,通过 NextContinuationToken 作为 continuation-token 查询参数.

import type { ZS3Objects } from "@focus-at/zs3/types";

const firstResponse = await client.exec<ZS3Objects>(
  { method: "GET", prefix: "reports/" },
  { query: { delimiter: "/", "max-keys": 100, "fetch-owner": true } },
);

const { data: firstPage } = await firstResponse.json();

if (firstPage.IsTruncated && firstPage.NextContinuationToken) {
  const nextResponse = await client.exec<ZS3Objects>(
    { method: "GET", prefix: "reports/" },
    {
      query: {
        delimiter: "/",
        "max-keys": 100,
        "fetch-owner": true,
        "continuation-token": firstPage.NextContinuationToken,
      },
    },
  );

  const { data: nextPage } =await nextResponse.json();

  console.log(nextPage);
}

处理对象版本

启用带有桶的版本 versioning 分资源。 然后列出版本并使用返回的版本 VersionId 以请求特定对象版本.

await client.exec(
  { method: "PUT", bucket: "my-bucket", key: "" },
  {
    query: { versioning: "" },
    headers: { "Content-Type": "application/xml" },
    body: "<VersioningConfiguration><Status>Enabled</Status></VersioningConfiguration>",
  },
);

const versionsResponse = await client.exec(
  { method: "GET", bucket: "my-bucket", key: "" },
  { query: { versions: "", prefix: "reports/" } },
);

const { data } = await versionsResponse.json();

// Use a VersionId returned by the version listing.
const objectVersion = await client.exec(
  { method: "GET", bucket: "my-bucket", key: "reports/annual.pdf" },
  { query: { versionId: "VERSION_ID" } },
);

设定对象元数据和标签

上传时发送用户元数据 x-amz-meta-* 头并可用 HEAD标记通过 tagging 分资源.

await client.exec(
  { method: "PUT", key: "reports/annual.pdf", body: file },
  {
    headers: {
      "Content-Type": "application/pdf",
      "x-amz-meta-source": "finance",
    },
  },
);

const metadata = await client.exec({ method: "HEAD", key: "reports/annual.pdf" });

console.log(metadata.headers.get("x-amz-meta-source"));

await client.exec(
  { method: "PUT", key: "reports/annual.pdf", body: taggingXml },
  {
    query: { tagging: "" },
    headers: { "Content-Type": "application/xml" },
  },
);

检查或更改对象的ACL,使用单独的 acl 子资源 :

const acl = await client.exec(
  { method: "GET", key: "reports/annual.pdf" },
  { query: { acl: "" } },
);

发送自定义请求

使用带有查询参数、信头和正文的自定义路径——例如,调用应用程序特定端点:

const response = await adminClient.exec(
  {
    method: "PUT",
    key: "admin/v3/add-user",
    body: JSON.stringify({ accessKey, status: "enabled" }),
  },
  {
    query: { source: "dashboard" },
    headers: { "Content-Type": "application/json" },
  },
);

见 examples/custom-request.ts 对于完整的例子.

将一个大对象按部件上传

多段上传被分成请求启动上传,发送每个部分,并完成. 留着 uploadId 和每个上传部分的ETag用于完成请求.

const initiated = await client.exec(
  { method: "POST", key: "archives/backup.zip" },
  { query: { uploads: "" } },
);

const { data: { UploadId } } = await initiated.json();

const partResponse = await client.exec(
  { method: "PUT", key: "archives/backup.zip", body: part },
  { query: { uploadId: UploadId, partNumber: 1 } },
);

const etag = partResponse.headers.get("etag");

const partsXml = `<CompleteMultipartUpload>
  <Part><PartNumber>1</PartNumber><ETag>${etag}</ETag></Part>
</CompleteMultipartUpload>`;

await client.exec(
  { method: "POST", key: "archives/backup.zip", body: partsXml },
  {
    query: { uploadId: UploadId },
    headers: { "Content-Type": "application/xml" },
  },
);

关于列出部件和中止上传,请参见 examples/multipart.ts。 。 。 .

API 覆盖图

区域涵盖的情况
签名AWS4 签名, 预先签名的 URL, 标准 fetch 签署后
弹夹列表/创建/删除; ACL, 版本化, 生命周期, 策略, 标签, CORS, 加密, 网站, 通知, 日志化, 复制, 公共访问块, 对象锁定
对象列表前缀、 分隔符、 最大键、 起步键、 取取所有者、 接续键页
对象Get, PUT, Head, DELETE, ACL, 标记, 用户元数据, 属性, 恢复, 保留/ 法律控件, 对象版本( 列表/ get/ 删除)
多块启动、上传部分、列表部分、完整、中止
自定义请求自定义路径、 查询参数、 页眉、 正文
错误状态处理和解析 S3 XML 出错有效载荷

实例

这个 examples/ 目录载有按工作流程分类的完整实例:

  • presigned-fetch.ts ——在服务器上创建一个预先签名的URL,并以标准发送请求 fetch()。 。 。 .
  • custom-request.ts ——自定义端点路径有查询参数,头,和一个请求正文.
  • buckets.ts ——列表,创建,并删除桶;ACL,版本,生命周期,政策,标签,CORS,加密,网站,通知,日志,复制,公众访问,以及对象锁定.
  • objects.ts - 列出和标出物体; prefix, (中文(简体) ), delimiter, (中文(简体) ), fetch-owner,从起始键列表, CRUD, ACL, 标记, 元数据, 副本, 属性, 恢复, 保留, 合法控件, 和列表/get/删除对象版本 .
  • multipart.ts ——启动,上传部分,列出部分,完成,并中止多段上传.

例子使用占位符证书和终点。 调整时提供自己的配置; 避免运行破坏性操作, 如桶或对象删除 .

版本与发布记录

@focus-at/zs3 共发布 21 个版本,首次发布于 2026/11/02;过去 12 个月发布了 21 个版本。

版本发布日期距今
0.1.0latest2026/11/079 天前
0.0.362026/11/0510 天前
0.0.352026/11/0510 天前
0.0.342026/11/0510 天前
0.0.322026/11/0510 天前
0.0.312026/11/0511 天前

关于 @focus-at/zs3 的常见问题

@focus-at/zs3 是什么?

Zero-dependency 3 KB S3客户端基于WS,Edge,Cloudflare Workers,Bun,Node,和浏览器运行时间的Web标准而构建.

如何安装 @focus-at/zs3?

在项目目录运行 npm install @focus-at/zs3,或使用 pnpm add / yarn add / bun add。

@focus-at/zs3 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@focus-at/zs3 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@focus-at/zs3 可以商用吗?

@focus-at/zs3 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@focus-at/zs3 的下载量有多少?

根据 npm 官方下载统计,@focus-at/zs3 在 2026/10/15 – 2026/11/13 这 30 天内被下载 4,099 次,日均约 137 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@focus-at/zs3 还在维护吗?

最新版本 0.1.0 发布于 2026/11/07(9 天前);至今共发布 21 个版本,其中过去 12 个月发布了 21 个;首次发布于 2026/11/02。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。