1import * as Effect from "effect/Effect";
2import type { LocationsSecret } from "./LocationsSecret.ts";
3import type { Secret } from "./Secret.ts";
4import { bindGcpHost } from "../Host.ts";
5import { grantFor, type BindingIam, type GcpHttpOp } from "../HttpBinding.ts";
6
7export type SecretBindingTarget = Secret | LocationsSecret;
8
9/**
10 * Shared HTTP scaffolding for Secret Manager bindings.
11 * NOT exported from index.ts.
12 */
13export const makeSecretHttpBinding = <I, A, E, Req = void>(options: {
14 tag: string;
15 iam: BindingIam;
16 operation: GcpHttpOp<I, A, E>;
17 toInput: (secretName: string, request: Req | undefined) => I;
18}) =>
19 Effect.gen(function* () {
20 const run = yield* options.operation;
21 return Effect.fn(function* (secret: SecretBindingTarget) {
22 // `name` is `projects/p/secrets/s` or, for regional secrets,
23 // `projects/p/locations/l/secrets/s`; both are secret IAM targets.
24 yield* bindGcpHost({
25 tag: options.tag,
26 resource: secret,
27 iam: [grantFor(options.iam, secret.name)],
28 });
29 const name = yield* secret.name;
30 return Effect.fn(`${options.tag}(${secret.LogicalId})`)(function* (
31 request?: Req,
32 ) {
33 return yield* run(options.toInput(yield* name, request));
34 });
35 });
36 });