1import type * as storage from "@distilled.cloud/gcp/storage_v1";
2import type * as Effect from "effect/Effect";
3import * as Binding from "../../Binding.ts";
4import type { RuntimeContext } from "../../RuntimeContext.ts";
5import type { Bucket } from "./Bucket.ts";
6import type {
7 ObjectNotFound,
8 ObjectRequestFailed,
9 PutObjectContent,
10} from "./ObjectMedia.ts";
11
12export type PutObjectRequest = PutObjectContent;
13
14/**
15 * Runtime binding that uploads an object's content to a Cloud Storage
16 * {@link Bucket} (multipart `objects.insert`), overwriting any live object
17 * with the same name. Grants `roles/storage.objectUser` on the bucket
18 * (overwrite needs delete permission, which `objectCreator` lacks).
19 *
20 * Bind this operation to a {@link Bucket} in a Function/Action init phase.
21 * Provide {@link PutObjectHttp}.
22 *
23 * ### Writing Objects
24 * **Example:** Write a text object
25 * ```typescript
26 * const putObject = yield* GCP.Storage.PutObject(bucket);
27 * yield* putObject({ name: "hello.txt", body: "Hello, World!" });
28 * ```
29 *
30 * **Example:** Write bytes with metadata
31 * ```typescript
32 * yield* putObject({
33 * name: "report.json",
34 * body: new TextEncoder().encode(JSON.stringify(report)),
35 * contentType: "application/json",
36 * metadata: { source: "nightly" },
37 * });
38 * ```
39 *
40 * @binding
41 * @category Storage
42 */
43export interface PutObject extends Binding.Service<
44 PutObject,
45 "GCP.Storage.PutObject",
46 (
47 bucket: Bucket,
48 ) => Effect.Effect<
49 (
50 request: PutObjectRequest,
51 ) => Effect.Effect<
52 storage.Storage_Object,
53 ObjectNotFound | ObjectRequestFailed,
54 RuntimeContext
55 >
56 >
57> {}
58
59export const PutObject = Binding.Service<PutObject>("GCP.Storage.PutObject");