1import * as secretsmanager from "@distilled.cloud/aws/secrets-manager";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as Binding from "../../Binding.ts";
5import type { Accessor } from "../../Output.ts";
6import { isBindingHost } from "../Lambda/Function.ts";
7import {
8 BatchGetSecretValue,
9 type BatchGetSecretValueRequest,
10} from "./BatchGetSecretValue.ts";
11import type { Secret } from "./Secret.ts";
12
13/**
14 * Bespoke (multi-secret) HTTP binding: `BatchGetSecretValue` targets a list
15 * of secrets, so it can't reuse the single-secret scaffolding — the account
16 * -level `secretsmanager:BatchGetSecretValue` action is granted on `*` and
17 * per-secret `GetSecretValue`/`DescribeSecret` on each bound secret's ARN.
18 */
19export const BatchGetSecretValueHttp = Layer.effect(
20 BatchGetSecretValue,
21 Effect.gen(function* () {
22 const batchGetSecretValue = yield* secretsmanager.batchGetSecretValue;
23
24 return Effect.fn(function* (secrets: readonly Secret[]) {
25 const SecretIds: Accessor<string>[] = [];
26 for (const secret of secrets) {
27 SecretIds.push(yield* secret.secretArn);
28 }
29 if (!globalThis.__ALCHEMY_RUNTIME__) {
30 const host = yield* Binding.Host;
31 if (isBindingHost(host)) {
32 yield* host.bind`Allow(${host}, AWS.SecretsManager.BatchGetSecretValue())`(
33 {
34 policyStatements: [
35 {
36 Effect: "Allow",
37 Action: ["secretsmanager:BatchGetSecretValue"],
38 Resource: ["*"],
39 },
40 ],
41 },
42 );
43 for (const secret of secrets) {
44 yield* host.bind`Allow(${host}, AWS.SecretsManager.BatchGetSecretValue(${secret}))`(
45 {
46 policyStatements: [
47 {
48 Effect: "Allow",
49 Action: [
50 "secretsmanager:GetSecretValue",
51 "secretsmanager:DescribeSecret",
52 ],
53 Resource: [secret.secretArn],
54 },
55 ],
56 },
57 );
58 }
59 }
60 }
61 return Effect.fn(
62 `AWS.SecretsManager.BatchGetSecretValue(${secrets
63 .map((secret) => secret.LogicalId)
64 .join(",")})`,
65 )(function* (request?: BatchGetSecretValueRequest) {
66 const secretIdList = [];
67 for (const secretId of SecretIds) {
68 secretIdList.push(yield* secretId);
69 }
70 return yield* batchGetSecretValue({
71 ...request,
72 SecretIdList: secretIdList,
73 });
74 });
75 });
76 }),
77);