1import * as notifications from "@distilled.cloud/aws/notifications";
2import * as Effect from "effect/Effect";
3import { createInternalTags, diffTags } from "../../Tags.ts";
4import { Region } from "../Region.ts";
5
6/**
7 * AWS User Notifications is managed from a single control-plane region.
8 * Every management API call must target `us-east-1` regardless of the
9 * ambient stack region (other regions reject with "API ...Activity cannot
10 * be called in us-west-2. Use us-east-1 instead"), so we pin the region on
11 * every distilled operation.
12 */
13const US_EAST_1 = "us-east-1";
14export const pinNotificationsRegion = <A, E, R>(
15 effect: Effect.Effect<A, E, R>,
16) => effect.pipe(Effect.provideService(Region, Effect.succeed(US_EAST_1)));
17
18/**
19 * Read the observed tags on a User Notifications resource, tolerating a
20 * not-yet-visible resource (returns `{}`).
21 */
22export const readNotificationsTags = Effect.fn(function* (arn: string) {
23 return yield* pinNotificationsRegion(
24 notifications.listTagsForResource({ arn }).pipe(
25 Effect.map((r) => (r.tags ?? {}) as Record<string, string>),
26 Effect.catchTag(
27 ["ResourceNotFoundException", "ValidationException"],
28 () => Effect.succeed({} as Record<string, string>),
29 ),
30 ),
31 );
32});
33
34/**
35 * Converge the tags on a User Notifications resource to the desired user
36 * tags merged with the internal Alchemy ownership tags, diffing against
37 * OBSERVED cloud tags so adoption converges.
38 */
39export const syncNotificationsTags = Effect.fn(function* (
40 arn: string,
41 id: string,
42 userTags: Record<string, string> | undefined,
43) {
44 const internalTags = yield* createInternalTags(id);
45 const desired = { ...userTags, ...internalTags };
46 const observed = yield* readNotificationsTags(arn);
47 const { upsert, removed } = diffTags(observed, desired);
48 if (upsert.length > 0) {
49 yield* pinNotificationsRegion(
50 notifications.tagResource({
51 arn,
52 tags: Object.fromEntries(upsert.map((t) => [t.Key, t.Value])),
53 }),
54 );
55 }
56 if (removed.length > 0) {
57 yield* pinNotificationsRegion(
58 notifications.untagResource({ arn, tagKeys: removed }),
59 );
60 }
61});