1import * as Effect from "effect/Effect";
2import * as Binding from "../../Binding.ts";
3import * as Output from "../../Output.ts";
4import { isBindingHost } from "../Lambda/Function.ts";
5import type { SearchJob } from "./SearchJob.ts";
6
7/**
8 * Shared scaffolding for BackupSearch HTTP bindings.
9 *
10 * NOT exported from `index.ts` — every `{Op}Http.ts` in this service is a
11 * thin `Layer.effect(Cap, makeSearchJobScopedHttpBinding({ … }))` over the
12 * builder below. Everything except the operation and the IAM action list is
13 * boilerplate.
14 *
15 * BackupSearch IAM actions live under the `backup-search:` service prefix.
16 */
17
18/**
19 * Build the impl Effect for a search-job-scoped operation: the runtime
20 * callable injects the bound {@link SearchJob}'s identifier as
21 * `SearchJobIdentifier` and the deploy-time half grants `actions` on the
22 * search job ARN.
23 */
24export const makeSearchJobScopedHttpBinding = <
25 I extends { SearchJobIdentifier: string },
26 A,
27 E,
28 R,
29>(options: {
30 /** Fully-qualified binding tag, e.g. `AWS.BackupSearch.ListSearchJobResults`. */
31 tag: string;
32 /** The distilled operation; `SearchJobIdentifier` is injected from the resource. */
33 operation: Effect.Effect<(input: I) => Effect.Effect<A, E>, never, R>;
34 /** IAM actions granted on the search job ARN. */
35 actions: readonly string[];
36}) =>
37 Effect.gen(function* () {
38 const op = yield* options.operation;
39
40 return Effect.fn(function* (searchJob: SearchJob) {
41 const SearchJobIdentifier = yield* searchJob.searchJobIdentifier;
42 if (!globalThis.__ALCHEMY_RUNTIME__) {
43 const host = yield* Binding.Host;
44 if (isBindingHost(host)) {
45 yield* host.bind`Allow(${host}, ${options.tag}(${searchJob}))`({
46 policyStatements: [
47 {
48 Effect: "Allow",
49 Action: [...options.actions],
50 Resource: [Output.interpolate`${searchJob.searchJobArn}`],
51 },
52 ],
53 });
54 }
55 }
56 return Effect.fn(`${options.tag}(${searchJob.LogicalId})`)(function* (
57 request?: Omit<I, "SearchJobIdentifier">,
58 ) {
59 return yield* op({
60 ...request,
61 SearchJobIdentifier: yield* SearchJobIdentifier,
62 } as I);
63 });
64 });
65 });