1import type * as Effect from "effect/Effect";
2import * as Binding from "../../Binding.ts";
3import type { RuntimeContext } from "../../RuntimeContext.ts";
4import { connectEnvPrefix as makeConnectEnvPrefix } from "../Connection/internal.ts";
5import type { ServerlessCache } from "./ServerlessCache.ts";
6
7/**
8 * Connection descriptor for an ElastiCache serverless cache. Alchemy does
9 * not bundle a valkey/redis client — pass these settings to the client of
10 * your choice (`iovalkey`, `ioredis`, `redis`, `memjs`, ...).
11 */
12export interface CacheConnectionInfo {
13 /** Primary endpoint hostname. */
14 host: string;
15 /** Primary endpoint port (6379 for valkey/redis, 11211 for memcached). */
16 port: number;
17 /** Reader endpoint hostname, when the engine exposes one. */
18 readerHost: string | undefined;
19 /** Reader endpoint port, when the engine exposes one. */
20 readerPort: number | undefined;
21 /**
22 * Serverless caches only accept TLS connections — always `true`.
23 */
24 tls: boolean;
25}
26
27/**
28 * Environment variable prefix under which {@link Connect} publishes the
29 * cache endpoint on the host Function, derived from the cache's logical ID.
30 * A cache with logical ID `SessionCache` yields `ELASTICACHE_SESSIONCACHE`
31 * and the variables `ELASTICACHE_SESSIONCACHE_HOST`,
32 * `ELASTICACHE_SESSIONCACHE_PORT`, and `ELASTICACHE_SESSIONCACHE_TLS`.
33 */
34export const connectEnvPrefix = (logicalId: string): string =>
35 makeConnectEnvPrefix("ELASTICACHE", logicalId);
36
37/**
38 * Runtime binding that resolves connection settings for an ElastiCache
39 * serverless cache.
40 *
41 * This is an environment-only binding: ElastiCache has no IAM-gated data
42 * plane for classic (non-RBAC) access, so the binding injects the cache's
43 * endpoint host/port as environment variables on the host Function and
44 * returns a typed {@link CacheConnectionInfo} at runtime. Network access is
45 * governed by VPC security groups, NOT IAM — the host Function must:
46 *
47 * 1. be attached to the cache's VPC (`vpc: { subnetIds, securityGroupIds }`), and
48 * 2. have a security group allowed ingress on the cache's port by one of the
49 * cache's `securityGroupIds`.
50 * ### Connecting to a Cache
51 * **Example:** Resolve Connection Info inside a Function
52 * ```typescript
53 * const connect = yield* ElastiCache.Connect(cache);
54 * // inside a handler:
55 * const { host, port, tls } = yield* connect;
56 * ```
57 *
58 * @binding
59 */
60export interface Connect extends Binding.Service<
61 Connect,
62 "AWS.ElastiCache.Connect",
63 (
64 cache: ServerlessCache,
65 ) => Effect.Effect<Effect.Effect<CacheConnectionInfo, never, RuntimeContext>>
66> {}
67export const Connect = Binding.Service<Connect>("AWS.ElastiCache.Connect");