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 Amazon DataZone delivers to EventBridge. Every
11 * DataZone event carries `metadata` (the entity's id/version) and a
12 * type-specific `data` object; the schema grows over time so both are kept
13 * open.
14 */
15export interface DataZoneEventDetail {
16 /** The versioned identity of the entity the event is about. */
17 metadata?: {
18 /** The id of the entity (e.g. the subscription request id). */
19 id?: string;
20 /** The revision/version of the entity. */
21 version?: string;
22 /** Additional metadata fields. */
23 [key: string]: unknown;
24 };
25 /**
26 * The type-specific event body — e.g. for `Subscription Request Created`:
27 * the domain, requester, and subscribed listing identifiers.
28 */
29 data?: {
30 /** The identifier of the domain the event originated in. */
31 domainId?: string;
32 /** Additional event fields (the schema grows over time). */
33 [key: string]: unknown;
34 };
35 /** Additional event fields (the schema grows over time). */
36 [key: string]: unknown;
37}
38
39/** An Amazon DataZone EventBridge event delivered to the handler. */
40export type DataZoneEvent = EventRecord<DataZoneEventDetail>;
41
42export interface DataZoneEventSourceProps extends EventRouteProps {
43 /**
44 * Logical id for the backing EventBridge rule.
45 * @default "DataZoneEvents"
46 */
47 id?: string;
48 /**
49 * Restrict to specific DataZone detail types, e.g.
50 * `["Subscription Request Created", "Subscription Created"]`. When omitted
51 * the host receives every event DataZone publishes (source
52 * `aws.datazone`).
53 */
54 detailTypes?: readonly string[];
55}
56
57/**
58 * Event source connecting Amazon DataZone notifications to the hosting
59 * compute. DataZone publishes its workflow events — subscription requests
60 * being created/accepted/rejected, subscriptions being granted, revoked, or
61 * cancelled, data source run state changes, asset changes, and domain
62 * changes — to the account's default EventBridge bus (source
63 * `aws.datazone`); this subscribes the host Function to those events so it
64 * can drive automated approval workflows or downstream syncs.
65 *
66 * DataZone publishes to EventBridge automatically — no additional resource
67 * is created besides the EventBridge rule targeting the host. Provide the
68 * host-specific implementation layer (e.g. `AWS.Lambda.EventSource`) on the
69 * Function effect.
70 *
71 * ### Consuming DataZone Events
72 * **Example:** Auto-approve Subscription Requests
73 * ```typescript
74 * import * as AWS from "alchemy/AWS";
75 *
76 * export default ApprovalFunction.make(
77 * { main: import.meta.url },
78 * Effect.gen(function* () {
79 * const acceptSubscriptionRequest =
80 * yield* AWS.DataZone.AcceptSubscriptionRequest(domain);
81 *
82 * yield* AWS.DataZone.consumeDataZoneEvents(
83 * { detailTypes: ["Subscription Request Created"] },
84 * (events) =>
85 * Stream.runForEach(events, (event) =>
86 * Effect.gen(function* () {
87 * const requestId = event.detail.metadata?.id;
88 * if (requestId !== undefined) {
89 * yield* acceptSubscriptionRequest({
90 * identifier: requestId,
91 * decisionComment: "auto-approved",
92 * }).pipe(Effect.ignore);
93 * }
94 * }),
95 * ),
96 * );
97 * return {};
98 * }).pipe(
99 * Effect.provide(AWS.Lambda.EventSource),
100 * Effect.provide(AWS.DataZone.AcceptSubscriptionRequestHttp),
101 * ),
102 * );
103 * ```
104 */
105export const consumeDataZoneEvents = <StreamReq = never, Req = never>(
106 props: DataZoneEventSourceProps,
107 process: (
108 events: Stream.Stream<DataZoneEvent, never, StreamReq>,
109 ) => Effect.Effect<void, never, Req>,
110) =>
111 consumeBusEvents(
112 props.id ?? "DataZoneEvents",
113 {
114 source: ["aws.datazone"],
115 ...(props.detailTypes !== undefined
116 ? { "detail-type": [...props.detailTypes] }
117 : {}),
118 },
119 { description: props.description, state: props.state },
120 process,
121 );