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 AWS Signer delivers to EventBridge for a signing-job
11 * status change. Fields not shared by every event kind are optional (the
12 * schema grows over time).
13 */
14export interface SigningJobEventDetail {
15 /** The signing job's new status (`Started`, `Succeeded`, `Failed`). */
16 status?: string;
17 /** The id of the signing job. */
18 job_id?: string;
19 /** The ARN of the ACM certificate used, for certificate-based platforms. */
20 certificate_arn?: string;
21 /** The signing platform id. */
22 platform?: string;
23 /** Additional event fields (the schema grows over time). */
24 [key: string]: unknown;
25}
26
27/** A Signer EventBridge event delivered to the handler. */
28export type SigningJobEvent = EventRecord<SigningJobEventDetail>;
29
30export interface SigningJobEventSourceProps extends EventRouteProps {
31 /**
32 * Logical id for the backing EventBridge rule.
33 * @default "SignerJobEvents"
34 */
35 id?: string;
36 /**
37 * Restrict to jobs reaching specific statuses (`Started`, `Succeeded`,
38 * `Failed`). Omit to receive every status change.
39 */
40 statuses?: readonly string[];
41}
42
43/**
44 * Event source connecting AWS Signer notifications to the hosting compute.
45 * Signer publishes signing-job status changes to the account's default
46 * EventBridge bus (source `aws.signer`, detail-type `Signer Job Status
47 * Change`); this subscribes the host Function to those events so it can
48 * react when a code-signing job starts, succeeds, or fails.
49 *
50 * Signer publishes to EventBridge automatically — no additional resource is
51 * created besides the EventBridge rule targeting the host. Provide the
52 * host-specific implementation layer (e.g. `AWS.Lambda.EventSource`) on the
53 * Function effect.
54 *
55 * ### Consuming Signing Job Events
56 * **Example:** React When Signing Fails
57 * ```typescript
58 * import * as AWS from "alchemy/AWS";
59 *
60 * export default AlertFunction.make(
61 * { main: import.meta.url },
62 * Effect.gen(function* () {
63 * yield* AWS.Signer.consumeSigningJobEvents(
64 * { statuses: ["Failed"] },
65 * (events) =>
66 * Stream.runForEach(events, (event) =>
67 * Effect.logError(`signing job ${event.detail.job_id} failed`),
68 * ),
69 * );
70 * return {};
71 * }).pipe(Effect.provide(AWS.Lambda.EventSource)),
72 * );
73 * ```
74 */
75export const consumeSigningJobEvents = <StreamReq = never, Req = never>(
76 props: SigningJobEventSourceProps,
77 process: (
78 events: Stream.Stream<SigningJobEvent, never, StreamReq>,
79 ) => Effect.Effect<void, never, Req>,
80) =>
81 consumeBusEvents(
82 props.id ?? "SignerJobEvents",
83 {
84 source: ["aws.signer"],
85 "detail-type": ["Signer Job Status Change"],
86 ...(props.statuses !== undefined
87 ? { detail: { status: [...props.statuses] } }
88 : {}),
89 },
90 { description: props.description, state: props.state },
91 process,
92 );