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

@playwright-labs/s3-core

v1.2.0

Published

Zero-dependency S3-compatible client (AWS Signature V4 over fetch) shared by @playwright-labs S3 packages

Readme

@playwright-labs/s3-core

Zero-dependency S3-compatible client — AWS Signature V4 over the global fetch. Works with AWS S3, MinIO, Cloudflare R2, and any other SigV4-compatible object storage.

Shared core for @playwright-labs/reporter-s3 and @playwright-labs/fixture-s3, but usable standalone.

Install

npm install @playwright-labs/s3-core

Requires Node.js 18+ (global fetch).

Usage

import { S3Client } from "@playwright-labs/s3-core";

const client = new S3Client({
  endpoint: "http://localhost:9000", // MinIO, R2, or https://s3.amazonaws.com
  region: "us-east-1",               // default
  accessKeyId: "minioadmin",
  secretAccessKey: "minioadmin",
  forcePathStyle: true,              // default; required by MinIO
  http: { timeoutMs: 30_000, retries: 2 }, // optional — per-attempt timeout + retry
});

await client.ensureBucket("artifacts");
await client.putObject("artifacts", "report.json", JSON.stringify({ ok: true }), {
  contentType: "application/json",
});

const body = await client.getObject("artifacts", "report.json"); // Buffer
await client.deleteObject("artifacts", "report.json");

API

new S3Client(options)

| Option | Type | Default | Description | |---|---|---|---| | endpoint | string | — (required) | S3-compatible endpoint URL | | region | string | "us-east-1" | Signing region | | accessKeyId | string | — (required) | Access key | | secretAccessKey | string | — (required) | Secret key | | forcePathStyle | boolean | true | Path-style URLs (endpoint/bucket/key); set false for virtual-host style (bucket.endpoint/key) | | http.timeoutMs | number | — | Per-attempt timeout (AbortSignal.timeout) | | http.retries | number | 0 | Extra attempts after network errors, timeouts, and 5xx (4xx and caller aborts are never retried) |

Methods

  • putObject(bucket, key, body, options?) — upload string | Buffer | Uint8Array | Readable | ReadableStream; options.contentType (default application/octet-stream), options.acl (e.g. private)
  • createWriteStream(bucket, key, options?) — writable stream over putObject (see below)
  • getObject(bucket, key, options?) — resolves with a Buffer; throws S3Error on 404
  • deleteObject(bucket, key, options?)
  • bucketExists(bucket, options?)HEAD, true/false; throws on other errors
  • createBucket(bucket, options?) — 409 (already owned) treated as success
  • ensureBucket(bucket, options?) — create unless it exists

Streams

putObject accepts a Node Readable or a web ReadableStream as the body, and createWriteStream returns a Node Writable to write into:

const stream = client.createWriteStream("logs", "run.log", {
  contentType: "text/plain",
});
stream.write("line 1\n");
stream.end("line 2\n");
await stream.done; // resolves after the upload succeeded; `finish` fires then too

Streams are buffered in memory and sent as a single signed PUT on end() — SigV4 signs the sha256 of the whole payload, so the body must be known upfront (no multipart / aws-chunked in this minimal client). A failed upload rejects done and emits error; an options.signal abort destroys the stream without uploading.

AbortSignal

Every method accepts options.signal — an AbortSignal cancelling the request, including all retry attempts:

const controller = new AbortController();
const download = client.getObject("artifacts", "big.bin", {
  signal: controller.signal,
});
controller.abort(); // download rejects

A caller abort is intentional and is never retried; timeouts and network errors are retried up to http.retries times.

S3Error

Thrown on any non-OK response; carries status and raw body.

Attachment-name marker

Helpers linking fixture-s3 and reporter-s3 — the fixture stores uploads as Playwright attachments named s3:<bucket>:<name>, the reporter routes them to <bucket> on run end:

formatS3AttachmentName("images", "photo.jpg"); // "s3:images:photo.jpg"
parseS3AttachmentName("s3:images:photo.jpg");  // { bucket: "images", name: "photo.jpg" }
parseS3AttachmentName("screenshot.png");       // null — not a marker

License

MIT