1import type * as runtime from "@cloudflare/workers-types";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import { makeBucketBinding, makeHelpers } from "./BucketBinding.ts";
5import { ReadBucket, type ReadBucketClient } from "./ReadBucket.ts";
6import type { GetOptions, ListOptions, Objects } from "./BucketTypes.ts";
7
8/**
9 * Implementation of the {@link ReadBucket} binding that uses a Worker binding.
10 */
11export const ReadBucketBinding = Layer.effect(
12 ReadBucket,
13 Effect.suspend(() => makeBucketBinding({ makeClient: makeRead })),
14);
15
16/** Build the read half of the binding client. */
17export const makeRead = ({
18 raw,
19 use,
20 wrapR2Object,
21 wrapR2ObjectOrBody,
22}: ReturnType<typeof makeHelpers>): ReadBucketClient => {
23 const wrapR2Objects = (objects: runtime.R2Objects): Objects =>
24 ({
25 objects: objects.objects.map(wrapR2Object),
26 delimitedPrefixes: objects.delimitedPrefixes,
27 ...("cursor" in objects ? { cursor: objects.cursor } : {}),
28 ...("truncated" in objects ? { truncated: objects.truncated } : {}),
29 }) as Objects;
30
31 return {
32 raw,
33 head: (key: string) =>
34 use((raw) => raw.head(key)).pipe(
35 Effect.map((object) => (object ? wrapR2Object(object) : object)),
36 ),
37 get: ((key: string, options?: GetOptions) =>
38 use((raw) => raw.get(key, options)).pipe(
39 Effect.map(wrapR2ObjectOrBody),
40 )) as any,
41 list: (options?: ListOptions) =>
42 use((raw) => raw.list(options)).pipe(Effect.map(wrapR2Objects)),
43 };
44};