1import * as Effect from "effect/Effect";
2import * as Layer from "effect/Layer";
3import * as Binding from "../../Binding.ts";
4import * as Output from "../../Output.ts";
5import { isBindingHost } from "../Lambda/Function.ts";
6import { Connect, connectEnvPrefix } from "./Connect.ts";
7import type { ServerlessCache } from "./ServerlessCache.ts";
8
9/**
10 * Environment-only implementation of {@link Connect}. At deploy time it
11 * publishes the cache endpoint as `ELASTICACHE_{LOGICAL_ID}_{HOST,PORT,TLS}`
12 * environment variables on the host Function; at runtime it resolves the
13 * same values into a typed connection descriptor. No IAM policy is attached
14 * — the classic valkey/redis/memcached data plane is governed by VPC
15 * security groups, not IAM.
16 */
17export const ConnectHttp = Layer.effect(
18 Connect,
19 Effect.gen(function* () {
20 return Effect.fn(function* (cache: ServerlessCache) {
21 const Host = yield* cache.endpointAddress;
22 const Port = yield* cache.endpointPort;
23 const ReaderHost = yield* cache.readerEndpointAddress;
24 const ReaderPort = yield* cache.readerEndpointPort;
25
26 if (!globalThis.__ALCHEMY_RUNTIME__) {
27 const host = yield* Binding.Host;
28 if (isBindingHost(host)) {
29 const prefix = connectEnvPrefix(cache.LogicalId);
30 yield* host.bind`Allow(${host}, AWS.ElastiCache.Connect(${cache}))`({
31 env: {
32 [`${prefix}_HOST`]: cache.endpointAddress,
33 // Lambda environment variables are strings — stringify the port.
34 [`${prefix}_PORT`]: Output.interpolate`${cache.endpointPort}`,
35 // Serverless caches are TLS-only.
36 [`${prefix}_TLS`]: "true",
37 },
38 });
39 }
40 }
41
42 return Effect.gen(function* () {
43 const host = yield* Host;
44 const port = yield* Port;
45 const readerHost = yield* ReaderHost;
46 const readerPort = yield* ReaderPort;
47 if (!host || port === undefined) {
48 return yield* Effect.die(
49 `ElastiCache endpoint for '${cache.LogicalId}' is not available yet`,
50 );
51 }
52 return {
53 host,
54 port,
55 readerHost,
56 readerPort,
57 tls: true,
58 };
59 });
60 });
61 }),
62);