1import * as codeartifact from "@distilled.cloud/aws/codeartifact";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as Binding from "../../Binding.ts";
5import { toWireSeconds } from "../../Util/Duration.ts";
6import { isBindingHost } from "../Lambda/Function.ts";
7import type { Domain } from "./Domain.ts";
8import {
9 GetAuthorizationToken,
10 type GetAuthorizationTokenRequest,
11} from "./GetAuthorizationToken.ts";
12
13/**
14 * HTTP implementation of {@link GetAuthorizationToken} over the CodeArtifact
15 * API. Domain-scoped (not repository-scoped): tokens authorize against every
16 * repository in the domain, and CodeArtifact exchanges the caller's
17 * credentials via `sts:GetServiceBearerToken`.
18 */
19export const GetAuthorizationTokenHttp = Layer.effect(
20 GetAuthorizationToken,
21 Effect.gen(function* () {
22 const op = yield* codeartifact.getAuthorizationToken;
23
24 return Effect.fn(function* (domain: Domain) {
25 const DomainName = yield* domain.domainName;
26 const Owner = yield* domain.owner;
27 if (!globalThis.__ALCHEMY_RUNTIME__) {
28 const host = yield* Binding.Host;
29 if (isBindingHost(host)) {
30 yield* host.bind`Allow(${host}, AWS.CodeArtifact.GetAuthorizationToken(${domain}))`(
31 {
32 policyStatements: [
33 {
34 Effect: "Allow",
35 Action: ["codeartifact:GetAuthorizationToken"],
36 Resource: [domain.domainArn],
37 },
38 {
39 // CodeArtifact exchanges the caller's credentials for the
40 // bearer token through STS on the caller's behalf.
41 Effect: "Allow",
42 Action: ["sts:GetServiceBearerToken"],
43 Resource: ["*"],
44 Condition: {
45 StringEquals: {
46 "sts:AWSServiceName": "codeartifact.amazonaws.com",
47 },
48 },
49 },
50 ],
51 },
52 );
53 }
54 }
55 return Effect.fn(
56 `AWS.CodeArtifact.GetAuthorizationToken(${domain.LogicalId})`,
57 )(function* (request?: GetAuthorizationTokenRequest) {
58 const owner = yield* Owner;
59 return yield* op({
60 domain: yield* DomainName,
61 ...(owner === "" ? {} : { domainOwner: owner }),
62 durationSeconds: toWireSeconds(request?.duration),
63 });
64 });
65 });
66 }),
67);