import { Boxes, Circle, Clock, Container, Database, HardDrive, Hammer, KeyRound, Layers, Lock, MessageSquare, Network, Radio, ScrollText, Scale, Server, ShieldCheck, SlidersHorizontal, Table2, Workflow, Waypoints, Zap, type LucideIcon, } from 'lucide-react' import type {CloudProvider} from '@/types/cloud' import apiGatewayIcon from '@/assets/aws-services/api-gateway.svg' import appConfigIcon from '@/assets/aws-services/appconfig.svg' import codeBuildIcon from '../../../../aws-icons-svg/Developer-Tools/CodeBuild.svg' import codePipelineIcon from '../../../../aws-icons-svg/Developer-Tools/CodePipeline.svg' import codeDeployIcon from '../../../../aws-icons-svg/Developer-Tools/CodeDeploy.svg' import cloudFormationIcon from '@/assets/aws-services/cloudformation.svg' import cloudWatchLogsIcon from '@/assets/aws-services/cloudwatch-logs.svg' import dynamoDbIcon from '@/assets/aws-services/dynamodb.svg' import ec2Icon from '@/assets/aws-services/ec2.svg' import ecrIcon from '@/assets/aws-services/ecr.svg' import ecsIcon from '@/assets/aws-services/ecs.svg' import eksIcon from '@/assets/aws-services/eks.svg' import elasticLoadBalancingIcon from '@/assets/aws-services/elastic-load-balancing.svg' import eventBridgeIcon from '@/assets/aws-services/eventbridge.svg' import iamIcon from '@/assets/aws-services/iam.svg' import kmsIcon from '@/assets/aws-services/kms.svg' import lambdaIcon from '@/assets/aws-services/lambda.svg' import parameterStoreIcon from '@/assets/aws-services/parameter-store.svg' import rdsIcon from '@/assets/aws-services/rds.svg' import s3Icon from '@/assets/aws-services/s3.svg' import secretsManagerIcon from '@/assets/aws-services/secrets-manager.svg' import sesIcon from '@/assets/aws-services/ses.svg' import snsIcon from '@/assets/aws-services/sns.svg' import sqsIcon from '@/assets/aws-services/sqs.svg' import stepFunctionsIcon from '@/assets/aws-services/step-functions.svg' import vpcIcon from '@/assets/aws-services/vpc.svg' import kinesisIcon from '../../../../aws-icons-svg/Analytics/Kinesis-Data-Streams.svg' import mskIcon from '../../../../aws-icons-svg/Analytics/Managed-Streaming-for-Apache-Kafka.svg' import mskConnectIcon from '../../../../aws-icons-svg/Analytics/MSK Connect Network Logo.svg' /** * Maps the server's `iconKey` hint to a component. * * Icon keys are additive and never load-bearing: the server can ship a service * whose key this build has never heard of, and the nav must still render. Passing * `undefined` as a JSX component throws and — before the ErrorBoundary lands — * would blank the whole app, so the fallback is not optional. */ const SERVICE_ICONS: Record = { storage: HardDrive, ecr: Container, database: Table2, nosql: Database, k8s: Boxes, compute: Server, containers: Container, networking: Network, apigateway: Waypoints, serverless: Zap, secrets: KeyRound, iac: Layers, messaging: MessageSquare, events: Radio, email: MessageSquare, queue: MessageSquare, logs: ScrollText, iam: ShieldCheck, kms: Lock, loadbalancing: Scale, parameters: SlidersHorizontal, configuration: SlidersHorizontal, scheduler: Clock, workflows: Workflow, codebuild: Hammer, codepipeline: Workflow, codedeploy: Workflow, kinesis: Radio, msk: Radio, 'msk-connect': Radio, } const AWS_SERVICE_ICON_ASSETS: Record = { apigateway: apiGatewayIcon, compute: ec2Icon, codebuild: codeBuildIcon, codepipeline: codePipelineIcon, codedeploy: codeDeployIcon, configuration: appConfigIcon, containers: ecsIcon, database: rdsIcon, ecr: ecrIcon, email: sesIcon, events: eventBridgeIcon, iac: cloudFormationIcon, iam: iamIcon, kms: kmsIcon, k8s: eksIcon, loadbalancing: elasticLoadBalancingIcon, logs: cloudWatchLogsIcon, messaging: sqsIcon, kinesis: kinesisIcon, msk: mskIcon, 'msk-connect': mskConnectIcon, nosql: dynamoDbIcon, notifications: snsIcon, networking: vpcIcon, parameters: parameterStoreIcon, secrets: secretsManagerIcon, serverless: lambdaIcon, storage: s3Icon, workflows: stepFunctionsIcon, } const FALLBACK_ICON: LucideIcon = Circle function serviceIcon(iconKey?: string): LucideIcon { return (iconKey && SERVICE_ICONS[iconKey]) || FALLBACK_ICON } interface ServiceIconProps { cloud?: CloudProvider iconKey?: string size?: number fallback?: LucideIcon className?: string } /** Renders official local AWS artwork, with the existing Lucide map as a safe fallback. */ export function ServiceIcon({cloud, iconKey, size = 16, fallback, className}: ServiceIconProps) { const asset = cloud === 'aws' && iconKey ? AWS_SERVICE_ICON_ASSETS[iconKey] : undefined const classes = ['service-icon-glyph', asset ? 'aws-service-icon' : '', className ?? ''].filter(Boolean).join(' ') if (asset) { return } const FallbackIcon = fallback ?? serviceIcon(iconKey) return