| 1 | import * as Effect from "effect/Effect"; |
| 2 | import * as Binding from "../../Binding.ts"; |
| 3 | import { isBindingHost } from "../Lambda/Function.ts"; |
| 4 | import type { CertificateAuthority } from "./CertificateAuthority.ts"; |
| 5 | |
| 6 | /** |
| 7 | * Options for {@link makeACMPCAHttpBinding}. |
| 8 | * |
| 9 | * @internal shared HTTP scaffolding for the ACM PCA capability bindings — |
| 10 | * not exported from the service index. |
| 11 | */ |
| 12 | export interface ACMPCAHttpBindingOptions< |
| 13 | Req extends { CertificateAuthorityArn: string }, |
| 14 | A, |
| 15 | E, |
| 16 | R, |
| 17 | > { |
| 18 | /** |
| 19 | * The ACM PCA action name, e.g. `"IssueCertificate"`. Used verbatim for |
| 20 | * the IAM action (`acm-pca:{action}`), the bind label, and the tracing |
| 21 | * span name. |
| 22 | */ |
| 23 | action: string; |
| 24 | /** |
| 25 | * The distilled ACM PCA operation. Every ACM PCA data-plane operation is |
| 26 | * keyed by `CertificateAuthorityArn`, which the binding injects from the |
| 27 | * bound {@link CertificateAuthority}. |
| 28 | */ |
| 29 | operation: Effect.Effect<(request: Req) => Effect.Effect<A, E>, never, R>; |
| 30 | } |
| 31 | |
| 32 | /** |
| 33 | * Build the implementation Effect for an ACM PCA HTTP capability binding. |
| 34 | * |
| 35 | * Every ACM PCA capability has the same shape — resolve the CA's ARN, |
| 36 | * register an IAM policy statement for `acm-pca:{action}` scoped to that |
| 37 | * CA at deploy time, and return a runtime callable that injects |
| 38 | * `CertificateAuthorityArn` into the operation's request. Only the |
| 39 | * operation and the action name differ, so each `{Op}Http.ts` is a thin |
| 40 | * `Layer.effect(Cap, makeACMPCAHttpBinding({ ... }))`. |
| 41 | * |
| 42 | * @internal |
| 43 | */ |
| 44 | export const makeACMPCAHttpBinding = < |
| 45 | Req extends { CertificateAuthorityArn: string }, |
| 46 | A, |
| 47 | E, |
| 48 | R, |
| 49 | >( |
| 50 | options: ACMPCAHttpBindingOptions<Req, A, E, R>, |
| 51 | ) => |
| 52 | Effect.gen(function* () { |
| 53 | const operation = yield* options.operation; |
| 54 | |
| 55 | return Effect.fn(function* (certificateAuthority: CertificateAuthority) { |
| 56 | const Arn = yield* certificateAuthority.certificateAuthorityArn; |
| 57 | if (!globalThis.__ALCHEMY_RUNTIME__) { |
| 58 | const host = yield* Binding.Host; |
| 59 | if (isBindingHost(host)) { |
| 60 | yield* host.bind`Allow(${host}, AWS.ACMPCA.${options.action}(${certificateAuthority}))`( |
| 61 | { |
| 62 | policyStatements: [ |
| 63 | { |
| 64 | Effect: "Allow", |
| 65 | Action: [`acm-pca:${options.action}`], |
| 66 | Resource: [certificateAuthority.certificateAuthorityArn], |
| 67 | }, |
| 68 | ], |
| 69 | }, |
| 70 | ); |
| 71 | } |
| 72 | } |
| 73 | return Effect.fn( |
| 74 | `AWS.ACMPCA.${options.action}(${certificateAuthority.LogicalId})`, |
| 75 | )(function* ( |
| 76 | request: Omit<Req, "CertificateAuthorityArn"> = {} as Omit< |
| 77 | Req, |
| 78 | "CertificateAuthorityArn" |
| 79 | >, |
| 80 | ) { |
| 81 | return yield* operation({ |
| 82 | ...request, |
| 83 | CertificateAuthorityArn: yield* Arn, |
| 84 | } as Req); |
| 85 | }); |
| 86 | }); |
| 87 | }); |