1import * as Alchemy from "alchemy";
2import { adopt } from "alchemy/AdoptPolicy";
3import * as Cloudflare from "alchemy/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 beta's DNS binding policy uses LogicalId to derive a
58 // stable SID, but Resource.ref returns a lazy output proxy.
59 Effect.map((zone) => withLogicalId(zone, "ManagedEndpointZone")),
60 ),
61 ),
62);
63
64export const RelayApiZone = RelayDeploymentConfig.pipe(
65 Effect.flatMap(({ stage, relayApiZoneName, managedEndpointZoneName }) =>
66 relayApiZoneName === managedEndpointZoneName
67 ? ManagedEndpointZone
68 : relayOwnsManagedEndpointZone(stage)
69 ? Cloudflare.Zone.Zone("RelayApiZone", { name: relayApiZoneName }).pipe(adopt(true))
70 : Cloudflare.Zone.Zone.ref("RelayApiZone", {
71 stage: MANAGED_ENDPOINT_ZONE_OWNER_STAGE,
72 }),
73 ),
74);