1import * as Alchemy from "alchemy";
2import { adopt } from "alchemy/AdoptPolicy";
3import * as Cloudflare from "@alchemy.run/cloudflare";
4import * as Config from "effect/Config";
5import * as Effect from "effect/Effect";
6import * as Option from "effect/Option";
7
8import {
9 MANAGED_ENDPOINT_ZONE_OWNER_STAGE,
10 relayOwnsManagedEndpointZone,
11 relayPublicDomainForStage,
12} from "./deploymentConfig.ts";
13
14function withLogicalId<Resource extends object>(resource: Resource, logicalId: string): Resource {
15 return new Proxy(resource, {
16 has: (target, property) => property === "LogicalId" || property in target,
17 get: (target, property, receiver) =>
18 property === "LogicalId" ? logicalId : Reflect.get(target, property, receiver),
19 });
20}
21
22export const RelayDeploymentConfig = Effect.gen(function* () {
23 const { stage } = yield* Alchemy.Stack;
24 const relayApiZoneName = yield* Config.NonEmptyString("RELAY_API_ZONE_NAME");
25 const managedEndpointZoneName = yield* Config.NonEmptyString("RELAY_TUNNEL_ZONE_NAME");
26 const relayPublicDomainOverride = yield* Config.String("RELAY_DOMAIN").pipe(
27 Config.option,
28 Config.map(
29 Option.flatMap((value) => {
30 const trimmed = value.trim();
31 return trimmed ? Option.some(trimmed) : Option.none();
32 }),
33 ),
34 );
35 const relayPublicDomain = Option.getOrElse(relayPublicDomainOverride, () =>
36 relayPublicDomainForStage(stage, relayApiZoneName),
37 );
38
39 return {
40 stage,
41 relayPublicDomain,
42 relayPublicOrigin: `https://${relayPublicDomain}`,
43 relayApiZoneName,
44 managedEndpointZoneName,
45 };
46});
47
48export const ManagedEndpointZone = RelayDeploymentConfig.pipe(
49 Effect.flatMap(({ stage, managedEndpointZoneName }) =>
50 relayOwnsManagedEndpointZone(stage)
51 ? Cloudflare.Zone.Zone("ManagedEndpointZone", { name: managedEndpointZoneName }).pipe(
52 adopt(true),
53 )
54 : Cloudflare.Zone.Zone.ref("ManagedEndpointZone", {
55 stage: MANAGED_ENDPOINT_ZONE_OWNER_STAGE,
56 }).pipe(
57 // Alchemy DNS policies need LogicalId for stable SIDs; Resource.ref returns a lazy proxy.
58 Effect.map((zone) => withLogicalId(zone, "ManagedEndpointZone")),
59 ),
60 ),
61);
62
63export const RelayApiZone = RelayDeploymentConfig.pipe(
64 Effect.flatMap(({ stage, relayApiZoneName, managedEndpointZoneName }) =>
65 relayApiZoneName === managedEndpointZoneName
66 ? ManagedEndpointZone
67 : relayOwnsManagedEndpointZone(stage)
68 ? Cloudflare.Zone.Zone("RelayApiZone", { name: relayApiZoneName }).pipe(adopt(true))
69 : Cloudflare.Zone.Zone.ref("RelayApiZone", {
70 stage: MANAGED_ENDPOINT_ZONE_OWNER_STAGE,
71 }),
72 ),
73);