ReviewOS

stacks/ts-cloud

S3Client: accept custom endpoint config (unblocks R2 / MinIO / DigitalOcean Spaces / Backblaze B2 in stacksjs/stacks#1896)

#116
Closed glennmichael123 opened this 2 months ago ·
2 months ago

Background

`S3Client` constructor today: `(region?: string, profile?: string)`. The endpoint is implicitly `s3.<region>.amazonaws.com`. Every S3-API-compatible store needs a custom endpoint:

ProviderEndpoint format
Cloudflare R2`https://<account-id>.r2.cloudflarestorage.com`
MinIOself-hosted, arbitrary URL
DigitalOcean Spaces`https://<region>.digitaloceanspaces.com`
Backblaze B2`https://s3.<region>.backblazeb2.com`
Wasabi`https://s3.<region>.wasabisys.com`

Without a way to override the endpoint, downstream packages can't ship adapters for any of these — they're all S3-API-compatible but the request URL needs to point elsewhere.

This blocks stacksjs/stacks#1896 (R2 driver). The framework's per-tenant scoping wrapper (`ScopedStorageAdapter`) already works with any S3-shaped adapter — only the endpoint config is missing.

Proposed API

new S3Client({ region: 'auto', endpoint: 'https://<account-id>.r2.cloudflarestorage.com', credentials })

// Or as a third positional arg if the constructor must stay positional-compatible:
new S3Client(region, profile, { endpoint })

The signing logic stays unchanged — SigV4 against the configured endpoint host. Apps using the default AWS endpoint see no behavior change.

Acceptance

  • S3Client accepts a custom endpoint field (constructor or options)
  • When provided, the endpoint host wins over the default AWS-derived URL for all requests (getObject, putObject, multipart, presigned URLs)
  • SigV4 signing uses the host from the configured endpoint, not the derived AWS host
  • Path-style addressing supported for MinIO-shaped endpoints (where buckets aren't in the subdomain)
  • Tests covering an R2-shaped endpoint round-trip + a path-style MinIO-shaped endpoint round-trip

Once this lands, the Stacks-side R2 driver is ~30 lines extending S3StorageAdapter with the right config defaults.

8 days ago

Roadmap relationship: tracked by #136 under master roadmap #132.

8 days ago

Implemented and verified on main in commit 824bc80.

Acceptance coverage:

  • S3Client accepts positional and options-object configuration with region, profile, endpoint, path style, and explicit credentials.
  • HTTP(S) endpoint origins preserve their exact protocol and host across ordinary requests, binary transfers, multipart uploads, and presigned URLs.
  • Virtual-hosted R2 and path-style HTTP MinIO requests sign the exact canonical URI sent on the wire.
  • Added R2 object round-trip, R2 presigned GET/PUT, MinIO path-style, binary upload, multipart upload, endpoint validation, and regression tests.
  • Documented R2 and MinIO configuration in docs/guide/providers.md.

Verification: 16 focused S3 tests pass; strict Pickier format/lint reports zero findings; the production package build generates all 55 UI pages.

Sign in to comment on this issue.