mirror of
https://github.com/VibedByKaKi/t3-code-android-nightly.git
synced 2026-10-12 13:37:19 +02:00
137 lines
4.4 KiB
TypeScript
137 lines
4.4 KiB
TypeScript
import * as CloudFront from "@/AWS/CloudFront";
|
|
import * as Lambda from "@/AWS/Lambda";
|
|
import * as S3 from "@/AWS/S3";
|
|
import type * as cloudfront from "@distilled.cloud/aws/cloudfront";
|
|
import * as Duration from "effect/Duration";
|
|
import * as Effect from "effect/Effect";
|
|
import * as Layer from "effect/Layer";
|
|
import * as Schedule from "effect/Schedule";
|
|
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");
|
|
|
|
// Distribution grants can still be propagating after the function URL is ready.
|
|
const authorizationPolicy = {
|
|
while: (
|
|
error:
|
|
| cloudfront.CreateInvalidationError
|
|
| cloudfront.GetInvalidationError
|
|
| cloudfront.ListInvalidationsError,
|
|
) => error._tag === "AccessDenied",
|
|
schedule: Schedule.spaced("3 seconds"),
|
|
times: 8,
|
|
};
|
|
|
|
export class CloudFrontTestFunction extends Lambda.Function<Lambda.Function>()(
|
|
"CloudFrontTestFunction",
|
|
) {}
|
|
|
|
export default CloudFrontTestFunction.make(
|
|
{
|
|
main,
|
|
functionUrl: true,
|
|
timeout: Duration.seconds(30),
|
|
},
|
|
Effect.gen(function* () {
|
|
const bucket = yield* S3.Bucket("InvalidationOriginBucket", {
|
|
forceDestroy: true,
|
|
});
|
|
const distribution = yield* CloudFront.Distribution("TestDistribution", {
|
|
// Deterministic marker so the test can find this distribution
|
|
// out-of-band via listDistributions.
|
|
comment: "alchemy-cf-bindings-fixture",
|
|
origins: [
|
|
{
|
|
id: "origin",
|
|
domainName: bucket.bucketRegionalDomainName,
|
|
s3Origin: true,
|
|
},
|
|
],
|
|
defaultCacheBehavior: {
|
|
targetOriginId: "origin",
|
|
viewerProtocolPolicy: "redirect-to-https",
|
|
allowedMethods: ["GET", "HEAD"],
|
|
cachedMethods: ["GET", "HEAD"],
|
|
minTtl: 0,
|
|
forwardedValues: {
|
|
QueryString: false,
|
|
Cookies: { Forward: "none" },
|
|
},
|
|
},
|
|
});
|
|
|
|
const createInvalidation =
|
|
yield* CloudFront.CreateInvalidation(distribution);
|
|
const getInvalidation = yield* CloudFront.GetInvalidation(distribution);
|
|
const listInvalidations = yield* CloudFront.ListInvalidations(distribution);
|
|
|
|
return {
|
|
fetch: Effect.gen(function* () {
|
|
const request = yield* HttpServerRequest;
|
|
const url = new URL(request.originalUrl);
|
|
const pathname = url.pathname;
|
|
|
|
if (request.method === "GET" && pathname === "/health") {
|
|
return yield* HttpServerResponse.json({ ok: true });
|
|
}
|
|
|
|
if (request.method === "POST" && pathname === "/invalidate") {
|
|
const body = (yield* request.json) as unknown as {
|
|
callerReference: string;
|
|
paths: string[];
|
|
};
|
|
const response = yield* createInvalidation({
|
|
InvalidationBatch: {
|
|
CallerReference: body.callerReference,
|
|
Paths: {
|
|
Quantity: body.paths.length,
|
|
Items: body.paths,
|
|
},
|
|
},
|
|
}).pipe(Effect.retry(authorizationPolicy));
|
|
return yield* HttpServerResponse.json({
|
|
invalidationId: response.Invalidation?.Id,
|
|
status: response.Invalidation?.Status,
|
|
});
|
|
}
|
|
|
|
if (request.method === "GET" && pathname === "/invalidation") {
|
|
const id = url.searchParams.get("id")!;
|
|
const response = yield* getInvalidation({ Id: id }).pipe(
|
|
Effect.retry(authorizationPolicy),
|
|
);
|
|
return yield* HttpServerResponse.json({
|
|
invalidationId: response.Invalidation?.Id,
|
|
status: response.Invalidation?.Status,
|
|
});
|
|
}
|
|
|
|
if (request.method === "GET" && pathname === "/invalidations") {
|
|
const response = yield* listInvalidations({}).pipe(
|
|
Effect.retry(authorizationPolicy),
|
|
);
|
|
return yield* HttpServerResponse.json({
|
|
invalidationIds: (response.InvalidationList?.Items ?? []).map(
|
|
(item) => item.Id,
|
|
),
|
|
});
|
|
}
|
|
|
|
return yield* HttpServerResponse.json(
|
|
{ error: "Not found" },
|
|
{ status: 404 },
|
|
);
|
|
}).pipe(Effect.orDie),
|
|
};
|
|
}).pipe(
|
|
Effect.provide(
|
|
Layer.mergeAll(
|
|
CloudFront.CreateInvalidationHttp,
|
|
CloudFront.GetInvalidationHttp,
|
|
CloudFront.ListInvalidationsHttp,
|
|
),
|
|
),
|
|
),
|
|
);
|