1import * as mq from "@distilled.cloud/aws/mq";
2import * as Effect from "effect/Effect";
3import { diffTags } from "../../Tags.ts";
4
5/**
6 * Amazon MQ tags are a plain string map on the wire. Drop any `undefined`
7 * values (the distilled map type is `{ [k: string]: string | undefined }`)
8 * so downstream diffing works on a clean `Record<string, string>`.
9 */
10export const toTagRecord = (
11 tags: { [key: string]: string | undefined } | undefined,
12): Record<string, string> =>
13 Object.fromEntries(
14 Object.entries(tags ?? {}).filter(
15 (entry): entry is [string, string] => typeof entry[1] === "string",
16 ),
17 );
18
19/**
20 * Sync tags on an Amazon MQ resource (broker or configuration): diff the
21 * OBSERVED cloud tags against the desired set and apply only the delta via
22 * `createTags` (upsert) / `deleteTags` (remove).
23 */
24export const syncMqTags = Effect.fn(function* (
25 arn: string,
26 observedTags: Record<string, string>,
27 desiredTags: Record<string, string>,
28) {
29 const { removed, upsert } = diffTags(observedTags, desiredTags);
30 if (upsert.length > 0) {
31 yield* mq.createTags({
32 ResourceArn: arn,
33 Tags: Object.fromEntries(upsert.map(({ Key, Value }) => [Key, Value])),
34 });
35 }
36 if (removed.length > 0) {
37 yield* mq.deleteTags({ ResourceArn: arn, TagKeys: removed });
38 }
39});