1import type * as Effect from "effect/Effect";
2import type * as Stream from "effect/Stream";
3import {
4 consumeBusEvents,
5 type EventRecord,
6 type EventRouteProps,
7} from "../EventBridge/EventSource.ts";
8
9/**
10 * The `detail` payload Redshift Serverless delivers to EventBridge. Every
11 * field is optional (the schema grows over time and varies by event kind).
12 */
13export interface RedshiftServerlessEventDetail {
14 /** Categories the event belongs to (e.g. `configuration`, `monitoring`). */
15 eventCategories?: string[];
16 /** Severity of the event (e.g. `INFO`, `ERROR`). */
17 severity?: string;
18 /** Human-readable description of what happened. */
19 eventMessage?: string;
20 /** Identifier of the namespace/workgroup/snapshot the event is about. */
21 sourceId?: string;
22 /** The kind of resource the event is about (e.g. `NAMESPACE`, `WORKGROUP`). */
23 sourceType?: string;
24 /** Additional event fields (the schema grows over time). */
25 [key: string]: unknown;
26}
27
28/** A Redshift Serverless EventBridge event delivered to the handler. */
29export type RedshiftServerlessEvent =
30 EventRecord<RedshiftServerlessEventDetail>;
31
32export interface RedshiftServerlessEventSourceProps extends EventRouteProps {
33 /**
34 * Logical id for the backing EventBridge rule.
35 * @default "RedshiftServerlessEvents"
36 */
37 id?: string;
38 /**
39 * Restrict to specific EventBridge `detail-type`s (e.g.
40 * `"Redshift Serverless Snapshot Event"`). Omit to receive every
41 * detail-type the `aws.redshift-serverless` source publishes.
42 */
43 detailTypes?: readonly string[];
44 /**
45 * Restrict to events about specific namespaces, workgroups, or snapshots
46 * (matched against the event's top-level `resources`, which carries the
47 * resource ARNs). Recommended when the account hosts more than one
48 * data warehouse.
49 */
50 resourceArns?: readonly string[];
51}
52
53/**
54 * Event source connecting Redshift Serverless notifications to the hosting
55 * compute. Redshift Serverless publishes namespace, workgroup, and snapshot
56 * lifecycle events — capacity changes, completed snapshots, configuration
57 * updates — to the account's default EventBridge bus (source
58 * `aws.redshift-serverless`); this subscribes the host Function to those
59 * events so it can react to completed snapshots or alert on workgroup
60 * status changes.
61 *
62 * Redshift Serverless publishes to EventBridge automatically — no
63 * additional resource is created besides the EventBridge rule targeting the
64 * host. Provide the host-specific implementation layer (e.g.
65 * `AWS.Lambda.EventSource`) on the Function effect.
66 *
67 * ### Consuming Redshift Serverless Events
68 * **Example:** React to Data Warehouse Events
69 * ```typescript
70 * import * as AWS from "alchemy/AWS";
71 *
72 * export default AlertFunction.make(
73 * { main: import.meta.url },
74 * Effect.gen(function* () {
75 * const namespaceArn = yield* namespace.namespaceArn;
76 * yield* AWS.RedshiftServerless.consumeRedshiftServerlessEvents(
77 * { resourceArns: [namespaceArn] },
78 * (events) =>
79 * Stream.runForEach(events, (event) =>
80 * Effect.logInfo(
81 * `${event["detail-type"]}: ${event.detail.eventMessage}`,
82 * ),
83 * ),
84 * );
85 * return {};
86 * }).pipe(Effect.provide(AWS.Lambda.EventSource)),
87 * );
88 * ```
89 */
90export const consumeRedshiftServerlessEvents = <StreamReq = never, Req = never>(
91 props: RedshiftServerlessEventSourceProps,
92 process: (
93 events: Stream.Stream<RedshiftServerlessEvent, never, StreamReq>,
94 ) => Effect.Effect<void, never, Req>,
95) =>
96 consumeBusEvents(
97 props.id ?? "RedshiftServerlessEvents",
98 {
99 source: ["aws.redshift-serverless"],
100 ...(props.detailTypes !== undefined
101 ? { "detail-type": [...props.detailTypes] }
102 : {}),
103 ...(props.resourceArns !== undefined
104 ? { resources: [...props.resourceArns] }
105 : {}),
106 },
107 { description: props.description, state: props.state },
108 process,
109 );