1import * as Effect from "effect/Effect";
2import * as Binding from "../../Binding.ts";
3import { isBindingHost } from "../Lambda/Function.ts";
4
5/**
6 * Shared scaffolding for Amazon Macie HTTP bindings.
7 *
8 * NOT exported from `index.ts` — every thin `{Op}Http.ts` in this service is
9 * a `Layer.effect(Cap, makeMacie2HttpBinding({ … }))` over the builder below.
10 * Everything except the operation and the IAM action list is boilerplate.
11 *
12 * Macie is an account/region singleton service: every operation is implicitly
13 * scoped to the caller's Macie session, so there is no identifier to inject —
14 * the caller's request is passed through as-is. Macie2 IAM actions do not
15 * support resource-level permissions (the session has no bindable ARN), so
16 * the deploy-time half grants `actions` on `*`.
17 */
18export const makeMacie2HttpBinding = <I, A, E, R>(options: {
19 /** Fully-qualified binding tag, e.g. `AWS.Macie2.ListFindings`. */
20 tag: string;
21 /** The distilled operation, invoked with the caller's request as-is. */
22 operation: Effect.Effect<(input: I) => Effect.Effect<A, E>, never, R>;
23 /** IAM actions granted on `*`. */
24 actions: readonly string[];
25}) =>
26 Effect.gen(function* () {
27 const op = yield* options.operation;
28
29 return Effect.fn(function* () {
30 if (!globalThis.__ALCHEMY_RUNTIME__) {
31 const host = yield* Binding.Host;
32 if (isBindingHost(host)) {
33 yield* host.bind`Allow(${host}, ${options.tag}())`({
34 policyStatements: [
35 {
36 Effect: "Allow",
37 Action: [...options.actions],
38 Resource: ["*"],
39 },
40 ],
41 });
42 }
43 }
44 return Effect.fn(options.tag)(function* (request?: I) {
45 return yield* op((request ?? {}) as I);
46 });
47 });
48 });