1import * as Effect from "effect/Effect";
2import * as Layer from "effect/Layer";
3import { authorizeWith } from "../HttpClientUtils.ts";
4import { makeHttpBucketBinding, type R2Auth } from "./BucketHttp.ts";
5import { makeReadR2HttpClient } from "./ReadBucketHttp.ts";
6import {
7 ReadWriteBucket,
8 type ReadWriteBucketClient,
9} from "./ReadWriteBucket.ts";
10import { makeWriteR2HttpClient } from "./WriteBucketHttp.ts";
11
12/**
13 * HTTP-backed implementation of the {@link ReadWriteBucket} binding.
14 *
15 * It creates a scoped {@link AccountApiToken} with the `Workers R2 Storage Read` and `Workers R2 Storage Write` permissions.
16 */
17export const ReadWriteBucketHttp = Layer.effect(
18 ReadWriteBucket,
19 Effect.suspend(() =>
20 makeHttpBucketBinding({
21 permissionGroups: ["Workers R2 Storage Read", "Workers R2 Storage Write"],
22 makeClient: (token, bucketName, jurisdiction) =>
23 makeReadWriteR2HttpClient(
24 { authorize: authorizeWith(token), accountId: token.accountId },
25 bucketName,
26 jurisdiction,
27 ),
28 }),
29 ),
30);
31
32/** Build the HTTP-backed {@link ReadWrite} over a bound token + bucket. */
33export const makeReadWriteR2HttpClient = (
34 auth: R2Auth,
35 bucketName: Effect.Effect<string>,
36 jurisdiction: Effect.Effect<string>,
37): ReadWriteBucketClient =>
38 ({
39 ...makeReadR2HttpClient(auth, bucketName, jurisdiction),
40 ...makeWriteR2HttpClient(auth, bucketName, jurisdiction),
41 }) satisfies ReadWriteBucketClient;