1import * as Effect from "effect/Effect";
2import * as Binding from "../Binding.ts";
3import type { Bucket } from "./Bucket.ts";
4import type {
5 RuntimeStorageMethods,
6 StorageBindingOptions,
7} from "./StorageBinding.ts";
8
9export interface WriteBucketClient extends RuntimeStorageMethods<
10 | "put"
11 | "delete"
12 | "deleteMany"
13 | "createMultipartUpload"
14 | "uploadPart"
15 | "completeMultipartUpload"
16 | "abortMultipartUpload"
17 | "listMultipartUploads"
18 | "listParts"
19> {
20 /** Presign an upload; the uploader must send the signed content type. */
21 presignPut(
22 key: string,
23 options?: { expiresIn?: number; contentType?: string },
24 ): ReturnType<RuntimeStorageMethods<"presign">["presign"]>;
25}
26
27/**
28 * Mutate a bucket. Managed clients request storage:read and storage:write because
29 * the current S3 service requires explicit read scope, despite the documented
30 * write-implies-read contract. Credentials reach descendant branches.
31 *
32 * ### Upload Objects
33 * **Example:** Raw bytes without manual credential handling
34 * ```typescript
35 * const files = yield* Neon.WriteBucket(uploads);
36 * yield* files.put("message.txt", "hello", { ContentType: "text/plain" });
37 * ```
38 *
39 * @binding
40 * @product Bucket
41 */
42export interface WriteBucket extends Binding.Service<
43 WriteBucket,
44 "Neon.WriteBucket",
45 (
46 bucket: Bucket,
47 options?: StorageBindingOptions,
48 ) => Effect.Effect<WriteBucketClient>
49> {}
50export const WriteBucket = Binding.Service<WriteBucket>("Neon.WriteBucket");