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 { isBindingHost } from "../Lambda/Function.ts";
6import { domainWideArns } from "./BindingHttp.ts";
7import {
8 CopyPackageVersions,
9 type CopyPackageVersionsRequest,
10} from "./CopyPackageVersions.ts";
11import type { Repository } from "./Repository.ts";
12
13/**
14 * HTTP implementation of {@link CopyPackageVersions} over the CodeArtifact
15 * API. Bespoke (not the shared repository scaffolding): the bound repository
16 * is injected as `destinationRepository`, and the copy also reads from the
17 * caller-chosen source repository, so the grant spans every repository and
18 * package in the domain.
19 */
20export const CopyPackageVersionsHttp = Layer.effect(
21 CopyPackageVersions,
22 Effect.gen(function* () {
23 const op = yield* codeartifact.copyPackageVersions;
24
25 return Effect.fn(function* (repository: Repository) {
26 const DomainName = yield* repository.domainName;
27 const DomainOwner = yield* repository.domainOwner;
28 const RepositoryName = yield* repository.repositoryName;
29 if (!globalThis.__ALCHEMY_RUNTIME__) {
30 const host = yield* Binding.Host;
31 if (isBindingHost(host)) {
32 yield* host.bind`Allow(${host}, AWS.CodeArtifact.CopyPackageVersions(${repository}))`(
33 {
34 policyStatements: [
35 {
36 Effect: "Allow",
37 Action: [
38 "codeartifact:CopyPackageVersions",
39 // The copy reads version metadata and assets from the
40 // source repository on the caller's behalf.
41 "codeartifact:ReadFromRepository",
42 "codeartifact:DescribePackageVersion",
43 ],
44 Resource: domainWideArns(repository),
45 },
46 ],
47 },
48 );
49 }
50 }
51 return Effect.fn(
52 `AWS.CodeArtifact.CopyPackageVersions(${repository.LogicalId})`,
53 )(function* (request: CopyPackageVersionsRequest) {
54 const owner = yield* DomainOwner;
55 return yield* op({
56 ...request,
57 domain: yield* DomainName,
58 ...(owner === "" ? {} : { domainOwner: owner }),
59 destinationRepository: yield* RepositoryName,
60 });
61 });
62 });
63 }),
64);