1import * as mi from "@distilled.cloud/aws/iot-managed-integrations";
2import * as Effect from "effect/Effect";
3import * as Redacted from "effect/Redacted";
4import { diffTags } from "../../Tags.ts";
5
6/**
7 * Unwrap a distilled `SensitiveString` (`string | Redacted<string>`) into a
8 * plain string, preserving `undefined`.
9 */
10export const unwrapSensitive = (
11 value: string | Redacted.Redacted<string> | undefined,
12): string | undefined =>
13 value === undefined
14 ? undefined
15 : typeof value === "string"
16 ? value
17 : Redacted.value(value);
18
19/**
20 * Convert the wire `TagsMap` (`Record<string, string | undefined>`) into a
21 * plain `Record<string, string>`, dropping entries without a value.
22 */
23export const toTagRecord = (
24 tags: { [key: string]: string | undefined } | undefined,
25): Record<string, string> =>
26 Object.fromEntries(
27 Object.entries(tags ?? {}).filter(
28 (entry): entry is [string, string] => typeof entry[1] === "string",
29 ),
30 );
31
32/**
33 * Reconcile the tags on an IoT Managed Integrations resource identified by
34 * ARN: diff OBSERVED cloud tags against the desired set and apply only the
35 * delta via tagResource/untagResource.
36 */
37export const syncManagedIntegrationsTags = Effect.fn(function* (
38 resourceArn: string,
39 observedTags: Record<string, string>,
40 desiredTags: Record<string, string>,
41) {
42 const { upsert, removed } = diffTags(observedTags, desiredTags);
43 if (upsert.length > 0) {
44 yield* mi.tagResource({
45 ResourceArn: resourceArn,
46 Tags: Object.fromEntries(upsert.map((tag) => [tag.Key, tag.Value])),
47 });
48 }
49 if (removed.length > 0) {
50 yield* mi.untagResource({ ResourceArn: resourceArn, TagKeys: removed });
51 }
52});