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 { ObjectContent, ObjectRequestFailed } from "./ObjectMedia.ts";
7
8export interface ListBucketOptions {
9 /** Only objects whose name starts with this prefix. */
10 prefix?: string;
11 /** Group names by this delimiter (e.g. `/`) into `prefixes`. */
12 delimiter?: string;
13 /** Maximum objects per page. */
14 maxResults?: number;
15 /** Page token from a previous `list`. */
16 pageToken?: string;
17}
18
19export interface ListBucketResult {
20 objects: storage.Storage_Object[];
21 /** Common prefixes when `delimiter` is set. */
22 prefixes: string[];
23 /** Pass to the next `list` call; `undefined` on the last page. */
24 nextPageToken: string | undefined;
25}
26
27/** Read-only client for one Cloud Storage bucket. */
28export interface ReadBucketClient {
29 /** Object metadata, or `undefined` when the object does not exist. */
30 head(
31 object: string,
32 ): Effect.Effect<
33 storage.Storage_Object | undefined,
34 storage.GetObjectsError,
35 RuntimeContext
36 >;
37 /** Object content, or `undefined` when the object does not exist. */
38 get(
39 object: string,
40 options?: { generation?: string },
41 ): Effect.Effect<
42 ObjectContent | undefined,
43 ObjectRequestFailed,
44 RuntimeContext
45 >;
46 /** One page of object listings. */
47 list(
48 options?: ListBucketOptions,
49 ): Effect.Effect<ListBucketResult, storage.ListObjectsError, RuntimeContext>;
50}
51
52/**
53 * Read access to a Cloud Storage {@link Bucket}: `head`, `get`, `list`.
54 * Grants `roles/storage.objectViewer` on the bucket only.
55 *
56 * ### Reading a bucket
57 * **Example:** Read an object and list a prefix
58 * ```typescript
59 * const uploads = yield* GCP.Storage.ReadBucket(bucket);
60 * const object = yield* uploads.get("hello.txt");
61 * const text = object && new TextDecoder().decode(object.body);
62 * const { objects } = yield* uploads.list({ prefix: "images/" });
63 * // …provided with Effect.provide(GCP.Storage.ReadBucketHttp)
64 * ```
65 *
66 * @binding
67 * @category Storage
68 */
69export interface ReadBucket extends Binding.Service<
70 ReadBucket,
71 "GCP.Storage.ReadBucket",
72 (bucket: Bucket) => Effect.Effect<ReadBucketClient>
73> {}
74
75export const ReadBucket = Binding.Service<ReadBucket>("GCP.Storage.ReadBucket");