t3-code-android-nightly/.repos/alchemy-effect/packages/alchemy/test/AWS/CodeArtifact/handler.ts
Julius Marminge 6f9cea00ae
chore(refs): sync Effect and Alchemy references to 4.0.1 and beta.80 (#16170)
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 13:22:30 -07:00

445 lines
16 KiB
TypeScript

import * as CodeArtifact from "@/AWS/CodeArtifact";
import * as Lambda from "@/AWS/Lambda";
import * as S3 from "@/AWS/S3";
import crypto from "node:crypto";
import * as Duration from "effect/Duration";
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as Redacted from "effect/Redacted";
import * as Schedule from "effect/Schedule";
import * as Stream from "effect/Stream";
import { HttpServerRequest } from "effect/http/HttpServerRequest";
import * as HttpServerResponse from "effect/http/HttpServerResponse";
import path from "pathe";
const main = path.resolve(import.meta.dirname, "handler.ts");
// Deterministic, lowercase CodeArtifact identifiers scoped to this suite
// (distinct from Repository.test.ts's `alchemy-test-ca` domain).
export const DOMAIN = "alchemy-test-ca-bind";
export const REPO = "alchemy-test-ca-bind-repo";
export const MIRROR = "alchemy-test-ca-bind-mirror";
const FORMAT = "generic" as const;
const NAMESPACE = "alchemy";
const PKG = "test-package";
const ASSET = "artifact.txt";
const contentFor = (version: string) => `hello codeartifact ${version}`;
export class CodeArtifactTestFunction extends Lambda.Function<Lambda.Function>()(
"CodeArtifactTestFunction",
) {}
export default CodeArtifactTestFunction.make(
{
main,
functionUrl: true,
// The publish → copy → dispose flows fan out several SDK calls; AWS's
// 3s default would intermittently time out.
timeout: Duration.seconds(60),
},
Effect.gen(function* () {
const domain = yield* CodeArtifact.Domain("Domain", {
domainName: DOMAIN,
});
const repo = yield* CodeArtifact.Repository("Repo", {
domain: domain.domainName,
repositoryName: REPO,
});
const mirror = yield* CodeArtifact.Repository("Mirror", {
domain: domain.domainName,
repositoryName: MIRROR,
});
// Marker store for the event source (events may arrive on another
// Lambda instance, so they must be observable out-of-band).
const bucket = yield* S3.Bucket("EventBucket", { forceDestroy: true });
const putObject = yield* S3.PutObject(bucket);
const getObject = yield* S3.GetObject(bucket);
// --- domain-scoped binding ---
const getToken = yield* CodeArtifact.GetAuthorizationToken(domain);
// --- repository-scoped bindings ---
const getEndpoint = yield* CodeArtifact.GetRepositoryEndpoint(repo);
const listPackages = yield* CodeArtifact.ListPackages(repo);
const describePackage = yield* CodeArtifact.DescribePackage(repo);
const describeVersion = yield* CodeArtifact.DescribePackageVersion(repo);
const listVersions = yield* CodeArtifact.ListPackageVersions(repo);
const listAssets = yield* CodeArtifact.ListPackageVersionAssets(repo);
const listDeps = yield* CodeArtifact.ListPackageVersionDependencies(repo);
const getReadme = yield* CodeArtifact.GetPackageVersionReadme(repo);
const getAsset = yield* CodeArtifact.GetPackageVersionAsset(repo);
const publish = yield* CodeArtifact.PublishPackageVersion(repo);
const updateStatus = yield* CodeArtifact.UpdatePackageVersionsStatus(repo);
const putOrigin = yield* CodeArtifact.PutPackageOriginConfiguration(repo);
const deletePackage = yield* CodeArtifact.DeletePackage(repo);
// --- mirror-scoped bindings (destination of the copy) ---
const copyToMirror = yield* CodeArtifact.CopyPackageVersions(mirror);
const listMirrorPackages = yield* CodeArtifact.ListPackages(mirror);
const disposeMirror = yield* CodeArtifact.DisposePackageVersions(mirror);
const deleteMirrorVersions =
yield* CodeArtifact.DeletePackageVersions(mirror);
const deleteMirrorPackage = yield* CodeArtifact.DeletePackage(mirror);
// --- event source ---
// CodeArtifact publishes every package version change to the default
// bus; write a marker object per event so /events/probe can observe the
// delivery out-of-band.
yield* CodeArtifact.consumePackageVersionStateChanges(
{ repositories: [REPO, MIRROR] },
(events) =>
Stream.runForEach(events, (event) =>
putObject({
Key: `events/${event.detail.packageVersion}`,
Body: JSON.stringify(event.detail),
ContentType: "application/json",
}).pipe(Effect.orDie, Effect.asVoid),
),
);
const publishVersion = Effect.fn(function* (
version: string,
unfinished: boolean,
) {
const content = contentFor(version);
const sha = yield* Effect.sync(() =>
crypto.createHash("sha256").update(content).digest("hex"),
);
return yield* publish({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
packageVersion: version,
assetName: ASSET,
assetContent: content,
assetSHA256: sha,
...(unfinished ? { unfinished: true } : {}),
});
});
return {
fetch: Effect.gen(function* () {
const request = yield* HttpServerRequest;
const url = new URL(request.originalUrl);
const pathname = url.pathname;
const param = (name: string) => url.searchParams.get(name) ?? "";
// Mint a domain authorization token; prove it comes back Redacted.
if (request.method === "GET" && pathname === "/token") {
const res = yield* getToken({ duration: "15 minutes" });
const token = res.authorizationToken;
return yield* HttpServerResponse.json({
redacted: Redacted.isRedacted(token),
length: (Redacted.isRedacted(token)
? Redacted.value(token)
: (token ?? "")
).length,
});
}
if (request.method === "GET" && pathname === "/endpoint") {
const res = yield* getEndpoint({ format: FORMAT });
return yield* HttpServerResponse.json({
endpoint: res.repositoryEndpoint,
});
}
// Delete the test package from both repositories so a retried test
// body starts from a clean slate — republishing an already-Published
// generic version raises the (deterministic) ConflictException.
if (request.method === "POST" && pathname === "/reset") {
yield* deletePackage({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
}).pipe(
Effect.catchTag("ResourceNotFoundException", () => Effect.void),
);
yield* deleteMirrorPackage({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
}).pipe(
Effect.catchTag("ResourceNotFoundException", () => Effect.void),
);
return yield* HttpServerResponse.json({ reset: true });
}
if (request.method === "POST" && pathname === "/publish") {
const res = yield* publishVersion(
param("version"),
param("unfinished") === "1",
);
return yield* HttpServerResponse.json({ status: res.status });
}
if (request.method === "GET" && pathname === "/package") {
const res = yield* describePackage({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
});
return yield* HttpServerResponse.json({
name: res.package?.name,
format: res.package?.format,
namespace: res.package?.namespace,
});
}
if (request.method === "GET" && pathname === "/version") {
const res = yield* describeVersion({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
packageVersion: param("version"),
});
return yield* HttpServerResponse.json({
version: res.packageVersion?.version,
status: res.packageVersion?.status,
});
}
if (request.method === "GET" && pathname === "/packages") {
const res = yield* listPackages({});
return yield* HttpServerResponse.json({
names: (res.packages ?? []).map((p) => p.package),
});
}
if (request.method === "GET" && pathname === "/versions") {
const res = yield* listVersions({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
});
return yield* HttpServerResponse.json({
versions: (res.versions ?? []).map((v) => v.version),
});
}
if (request.method === "GET" && pathname === "/assets") {
const res = yield* listAssets({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
packageVersion: param("version"),
});
return yield* HttpServerResponse.json({
assets: (res.assets ?? []).map((a) => a.name),
});
}
if (request.method === "GET" && pathname === "/asset") {
const res = yield* getAsset({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
packageVersion: param("version"),
asset: ASSET,
});
const content = yield* Stream.mkString(
Stream.decodeText(res.asset!),
).pipe(Effect.orDie);
return yield* HttpServerResponse.json({ content });
}
// Generic packages have no readme — CodeArtifact answers with the
// typed ResourceNotFoundException ("The readme file of this package
// version is not found"); surface the tag instead of dying.
if (request.method === "GET" && pathname === "/readme") {
const res = yield* getReadme({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
packageVersion: param("version"),
}).pipe(
Effect.map((r) => ({ readme: r.readme ?? "", error: undefined })),
Effect.catchTag(
["ResourceNotFoundException", "ValidationException"],
(e) => Effect.succeed({ readme: undefined, error: e._tag }),
),
);
return yield* HttpServerResponse.json(res);
}
// Generic packages record no dependency manifest — surfaces the
// typed not-found/validation error instead of dying.
if (request.method === "GET" && pathname === "/deps") {
const res = yield* listDeps({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
packageVersion: param("version"),
}).pipe(
Effect.map((r) => ({
dependencies: (r.dependencies ?? []).map((d) => d.package),
error: undefined,
})),
Effect.catchTag(
["ResourceNotFoundException", "ValidationException"],
(e) => Effect.succeed({ dependencies: undefined, error: e._tag }),
),
);
return yield* HttpServerResponse.json(res);
}
if (request.method === "POST" && pathname === "/status") {
const res = yield* updateStatus({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
versions: [param("version")],
targetStatus: param("target"),
});
return yield* HttpServerResponse.json({
successful: Object.keys(res.successfulVersions ?? {}),
});
}
if (request.method === "POST" && pathname === "/origin") {
const res = yield* putOrigin({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
restrictions: { publish: "ALLOW", upstream: "BLOCK" },
});
return yield* HttpServerResponse.json({
restrictions: res.originConfiguration?.restrictions,
});
}
if (request.method === "POST" && pathname === "/copy") {
const res = yield* copyToMirror({
sourceRepository: REPO,
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
versions: [param("version")],
});
return yield* HttpServerResponse.json({
successful: Object.keys(res.successfulVersions ?? {}),
});
}
if (request.method === "GET" && pathname === "/mirror/packages") {
const res = yield* listMirrorPackages({});
return yield* HttpServerResponse.json({
names: (res.packages ?? []).map((p) => p.package),
});
}
if (request.method === "POST" && pathname === "/mirror/dispose") {
const res = yield* disposeMirror({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
versions: [param("version")],
});
return yield* HttpServerResponse.json({
successful: Object.keys(res.successfulVersions ?? {}),
});
}
if (
request.method === "POST" &&
pathname === "/mirror/delete-versions"
) {
const res = yield* deleteMirrorVersions({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
versions: [param("version")],
});
return yield* HttpServerResponse.json({
successful: Object.keys(res.successfulVersions ?? {}),
});
}
if (
request.method === "POST" &&
pathname === "/mirror/delete-package"
) {
yield* deleteMirrorPackage({
format: FORMAT,
namespace: NAMESPACE,
package: PKG,
}).pipe(
Effect.catchTag("ResourceNotFoundException", () => Effect.void),
);
return yield* HttpServerResponse.json({ deleted: true });
}
// Publish a fresh version, then poll for the event-source marker the
// state-change handler wrote to S3 (bounded well under the 60s
// function timeout).
if (request.method === "GET" && pathname === "/events/probe") {
const version = param("version");
// A retried probe re-publishes the same version — CodeArtifact
// rejects updates to a Published generic version with the typed
// ConflictException; the event already fired, so just poll.
yield* publishVersion(version, false).pipe(
Effect.catchTag("ConflictException", () =>
Effect.succeed(undefined),
),
);
const seen = yield* getObject({ Key: `events/${version}` }).pipe(
Effect.retry({
while: (e): boolean => e._tag === "NoSuchKey",
schedule: Schedule.spaced("2 seconds"),
times: 12,
}),
Effect.map(() => true),
Effect.catchTag("NoSuchKey", () => Effect.succeed(false)),
);
return yield* HttpServerResponse.json({ seen, version });
}
return yield* HttpServerResponse.json(
{ error: "Not found", method: request.method, pathname },
{ status: 404 },
);
}).pipe(
// Surface typed errors in the 500 body so the test's transient-retry
// logs show the real failure instead of an opaque Internal Server
// Error.
Effect.catch((e) =>
HttpServerResponse.json(
{
error: (e as { _tag?: string })._tag ?? "UnknownError",
message: String(e),
},
{ status: 500 },
),
),
Effect.orDie,
),
};
}).pipe(
Effect.provide(
Layer.mergeAll(
Lambda.EventSource,
CodeArtifact.GetAuthorizationTokenHttp,
CodeArtifact.GetRepositoryEndpointHttp,
CodeArtifact.ListPackagesHttp,
CodeArtifact.DescribePackageHttp,
CodeArtifact.DescribePackageVersionHttp,
CodeArtifact.ListPackageVersionsHttp,
CodeArtifact.ListPackageVersionAssetsHttp,
CodeArtifact.ListPackageVersionDependenciesHttp,
CodeArtifact.GetPackageVersionReadmeHttp,
CodeArtifact.GetPackageVersionAssetHttp,
CodeArtifact.PublishPackageVersionHttp,
CodeArtifact.UpdatePackageVersionsStatusHttp,
CodeArtifact.PutPackageOriginConfigurationHttp,
CodeArtifact.CopyPackageVersionsHttp,
CodeArtifact.DisposePackageVersionsHttp,
CodeArtifact.DeletePackageVersionsHttp,
CodeArtifact.DeletePackageHttp,
S3.PutObjectHttp,
S3.GetObjectHttp,
),
),
),
);