diff --git a/.changeset/dirty-facts-hammer.md b/.changeset/dirty-facts-hammer.md new file mode 100644 index 000000000..3599b9707 --- /dev/null +++ b/.changeset/dirty-facts-hammer.md @@ -0,0 +1,33 @@ +--- +'@clickhouse/click-ui': minor +--- + +Introduces a centralised asset configuration with unified aliases and deprecated name mappings. This provides a single source of truth for asset name resolution across all asset types (Icons, Logos, Flags, and Payments), helping to resolve circular dependencies while offering a flexible aliasing system. + +### Why aliases? + +Asset naming conventions use kebab-case (e.g., `c-sharp`, `arrow-down`) to facilitate file organisation and ensure valid JavaScript identifiers. However, users may prefer more intuitive names that don't follow these conventions. Aliases bridge this gap. + +For example, `c#` contains a `#` character which is not a valid JavaScript identifier, but users might still prefer using `c#` over `c-sharp`. + +### How to use aliases + +Aliases are defined in `src/components/Assets/config.ts` under `ASSET_NAME_MAPPINGS.aliases`: + +```tsx +export const ASSET_NAME_MAPPINGS = { + aliases: { + 'c#': 'c-sharp', + // Add more aliases as needed + } as AssetAliasMap, + // ... +}; +``` + +The alias is then automatically resolved when using any asset component: + +```tsx +// Both of these work identically: + + +``` diff --git a/src/components/Assets/Flags/system/Flag.tsx b/src/components/Assets/Flags/system/Flag.tsx index 5ad10234e..ed67b35c1 100644 --- a/src/components/Assets/Flags/system/Flag.tsx +++ b/src/components/Assets/Flags/system/Flag.tsx @@ -2,12 +2,24 @@ import { SVGAttributes } from 'react'; import { useTheme } from 'styled-components'; import { getFallbackThemeName } from '@/theme/theme.utils'; import { SvgImageElement } from '@/components/Icon/SvgImageElement'; -import { FlagProps } from './types'; -import { resolveFlagName } from './retroactiveNames'; +import { FlagName, FlagProps } from './types'; +import { + createAssetResolver, + type AssetAlias, + type AssetDeprecatedName, +} from '@/components/Assets/config'; import FlagsDark from './FlagsDark'; import FlagsLight from './FlagsLight'; -const Flag = ({ name, theme, size, ...props }: FlagProps) => { +const resolveFlagName = createAssetResolver(); + +export { resolveFlagName }; + +export interface FlagPropsWithAliases extends Omit { + name: FlagName | AssetAlias | AssetDeprecatedName; +} + +const Flag = ({ name, theme, size, ...props }: FlagPropsWithAliases) => { const { name: themeName } = useTheme(); const resolvedName = resolveFlagName(name); const resolvedTheme = getFallbackThemeName(theme ?? themeName); diff --git a/src/components/Assets/Flags/system/FlagsDark.ts b/src/components/Assets/Flags/system/FlagsDark.ts index 415465102..934aa9a88 100644 --- a/src/components/Assets/Flags/system/FlagsDark.ts +++ b/src/components/Assets/Flags/system/FlagsDark.ts @@ -30,7 +30,7 @@ import { FlagName } from './types'; import type { SVGAssetProps } from '@/types'; import type { ComponentType } from 'react'; -const FlagsLight: Record> = { +const FlagsDark: Record> = { australia: Australia, brazil: Brazil, canada: Canada, @@ -54,4 +54,4 @@ const FlagsLight: Record> = { 'united-states': United_States, }; -export default FlagsLight; +export default FlagsDark; diff --git a/src/components/Assets/Flags/system/retroactiveNames.ts b/src/components/Assets/Flags/system/retroactiveNames.ts deleted file mode 100644 index 8c46a3bde..000000000 --- a/src/components/Assets/Flags/system/retroactiveNames.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { FlagName } from './types'; - -export const FLAG_NAME_RETRO_MAP: Record = { - ae: 'united-arab-emirates', - au: 'australia', - br: 'brazil', - ca: 'canada', - ch: 'switzerland', - de: 'germany', - eu: 'european-union', - gb: 'great-britain', - hk: 'hong-kong', - id: 'indonesia', - ie: 'ireland', - il: 'israel', - in: 'india', - jp: 'japan', - nl: 'netherlands', - sg: 'singapore', - kr: 'south-korea', - sw: 'sweden', - uk: 'united-kingdom', - usa: 'united-states', - za: 'south-africa', - - Australia: 'australia', - Brazil: 'brazil', - Canada: 'canada', - EuropeanUnion: 'european-union', - Germany: 'germany', - GreatBritain: 'great-britain', - HongKong: 'hong-kong', - India: 'india', - Indonesia: 'indonesia', - Ireland: 'ireland', - Israel: 'israel', - Japan: 'japan', - Netherlands: 'netherlands', - Singapore: 'singapore', - SouthAfrica: 'south-africa', - SouthKorea: 'south-korea', - Sweden: 'sweden', - Switzerland: 'switzerland', - UnitedArabEmirates: 'united-arab-emirates', - UnitedKingdom: 'united-kingdom', - UnitedStates: 'united-states', -}; - -// TODO: Retroactive support for simple name cases -// causes unwanted complexity. Isn't it best to make it -// a breaking change? A find and replace solves it quick - -/** @deprecated Use lower case kebab naming, e.g. 'my-country-name' instead */ -export type DeprecatedFlagName = keyof typeof FLAG_NAME_RETRO_MAP; - -export const resolveFlagName = (name: string): FlagName => { - const mapped = FLAG_NAME_RETRO_MAP[name]; - if (mapped) { - console.warn(`Flag name "${name}" is deprecated, use "${mapped}" instead`); - return mapped; - } - return name as FlagName; -}; diff --git a/src/components/Assets/Icons/system/Icon.tsx b/src/components/Assets/Icons/system/Icon.tsx index 08b281b1e..3a5b8411d 100644 --- a/src/components/Assets/Icons/system/Icon.tsx +++ b/src/components/Assets/Icons/system/Icon.tsx @@ -1,13 +1,25 @@ import { SVGAttributes } from 'react'; import { useTheme } from 'styled-components'; import { getFallbackThemeName } from '@/theme/theme.utils'; -import { resolveIconName } from './retroactiveNames'; -import IconsLight from './IconsLight'; -import IconsDark from './IconsDark'; import { SvgImageElement } from '@/components/Icon/SvgImageElement'; -import { IconProps } from './types'; +import { IconName, IconProps } from './types'; +import { + createAssetResolver, + type AssetAlias, + type AssetDeprecatedName, +} from '@/components/Assets/config'; +import IconsDark from './IconsDark'; +import IconsLight from './IconsLight'; + +const resolveIconName = createAssetResolver(); + +export { resolveIconName }; + +export interface IconPropsWithAliases extends Omit { + name: IconName | AssetAlias | AssetDeprecatedName; +} -const Icon = ({ name, theme, size, ...props }: IconProps) => { +const Icon = ({ name, theme, size, ...props }: IconPropsWithAliases) => { const { name: themeName } = useTheme(); const resolvedName = resolveIconName(name); const resolvedTheme = getFallbackThemeName(theme ?? themeName); diff --git a/src/components/Assets/Icons/system/retroactiveNames.ts b/src/components/Assets/Icons/system/retroactiveNames.ts deleted file mode 100644 index e772a2196..000000000 --- a/src/components/Assets/Icons/system/retroactiveNames.ts +++ /dev/null @@ -1,181 +0,0 @@ -import type { IconName, DeprecatedIconName } from './types'; - -export const ICON_NAME_RETRO_MAP: Record = { - Activity: 'activity', - Alarm: 'alarm', - ArrowDirections: 'arrow-directions', - ArrowDown: 'arrow-down', - ArrowLeft: 'arrow-left', - ArrowRight: 'arrow-right', - ArrowTriangle: 'arrow-triangle', - ArrowUp: 'arrow-up', - AuthApp: 'auth-app', - AuthSms: 'auth-sms', - Backups: 'backups', - BarChart: 'bar-chart', - Bell: 'bell', - Beta: 'beta', - Blog: 'blog', - Bold: 'bold', - Book: 'book', - Brackets: 'brackets', - Briefcase: 'briefcase', - Building: 'building', - BurgerMenu: 'burger-menu', - Calendar: 'calendar', - CalendarWithTime: 'calendar-with-time', - Cards: 'cards', - CellTower: 'cell-tower', - ChartArea: 'chart-area', - ChartBarHorizontal: 'chart-bar-horizontal', - ChartCloud: 'chart-cloud', - ChartDonut: 'chart-donut', - ChartHeatmap: 'chart-heatmap', - ChartScatter: 'chart-scatter', - ChartSquare: 'chart-square', - ChartStackedHorizontal: 'chart-stacked-horizontal', - ChartStackedVertical: 'chart-stacked-vertical', - ChatIcon: 'chat', - CheckIcon: 'check', - CheckInCircle: 'check-in-circle', - ChevronDown: 'chevron-down', - ChevronLeft: 'chevron-left', - ChevronRight: 'chevron-right', - ChevronUp: 'chevron-up', - Circle: 'circle', - Clock: 'clock', - Cloud: 'cloud', - CloudKeys: 'cloud-keys', - Code: 'code', - CodeInSquare: 'code-in-square', - Connect: 'connect', - ConnectAlt: 'connect-alt', - Console: 'console', - Copy: 'copy', - Cpu: 'cpu', - CreditCard: 'credit-card', - CrossIcon: 'cross', - Data: 'data', - DataLakes: 'data-lakes', - DatabaseIcon: 'database', - Disk: 'disk', - Display: 'display', - Document: 'document', - Dot: 'dot', - DotsHorizontal: 'dots-horizontal', - DotsTriangle: 'dots-triangle', - DotsVertical: 'dots-vertical', - DotsVerticalDouble: 'dots-vertical-double', - DoubleCheckIcon: 'double-check', - Download: 'download', - DownloadInCircle: 'download-in-circle', - Email: 'email', - Empty: 'empty', - Enter: 'enter', - Eye: 'eye', - EyeClosed: 'eye-closed', - FilterIcon: 'filter', - Fire: 'fire', - Flag: 'flag', - Flash: 'flash', - Flask: 'flask', - FolderClosed: 'folder-closed', - FolderOpen: 'folder-open', - Gear: 'gear', - Gift: 'gift', - GitMerge: 'git-merge', - Globe: 'globe', - Hexagon: 'hexagon', - HistoryIcon: 'history', - Home: 'home', - HorizontalLoading: 'horizontal-loading', - Http: 'http', - HttpMonitoring: 'http-monitoring', - InfoInCircleIcon: 'info-in-circle', - InformationIcon: 'information', - InsertRowIcon: 'insert-row', - Integrations: 'integrations', - Italic: 'italic', - Key: 'key', - Keys: 'keys', - Lifebuoy: 'lifebuoy', - LightBulb: 'light-bulb', - LightBulbOn: 'light-bulb-on', - Lightening: 'lightening', - LineInCircle: 'line-in-circle', - ListBulleted: 'list-bulleted', - ListNumbered: 'list-numbered', - Loading: 'loading', - LoadingAnimated: 'loading-animated', - Lock: 'lock', - MapPin: 'map-pin', - Mcp: 'mcp', - Metrics: 'metrics', - MetricsAlt: 'metrics-alt', - Minus: 'minus', - Moon: 'moon', - NoCloud: 'no-cloud', - Pause: 'pause', - Payment: 'payment', - Pencil: 'pencil', - PieChart: 'pie-chart', - Pipe: 'pipe', - Play: 'play', - PlayInCircle: 'play-in-circle', - Plug: 'plug', - Plus: 'plus', - Popout: 'popout', - PopoverArrow: 'popover-arrow', - PuzzlePiece: 'puzzle-piece', - Query: 'query', - Question: 'question', - Refresh: 'refresh', - ResizeArrowsHorizontal: 'resize-arrows-horizontal', - ResizeArrowsVertical: 'resize-arrows-vertical', - Rocket: 'rocket', - SandGlass: 'sand-glass', - Search: 'search', - Secure: 'secure', - Server: 'server', - Services: 'services', - Settings: 'settings', - Share: 'share', - ShareArrow: 'share-arrow', - ShareNetwork: 'share-network', - Sleep: 'sleep', - SlideIn: 'slide-in', - SlideOut: 'slide-out', - SortAltIcon: 'sort-alt', - SortIcon: 'sort', - Sparkle: 'sparkle', - Speaker: 'speaker', - Speed: 'speed', - Square: 'square', - Star: 'star', - Stop: 'stop', - Support: 'support', - Table: 'table', - Taxi: 'taxi', - TextSlash: 'text-slash', - ThumbsDown: 'thumbs-down', - ThumbsUp: 'thumbs-up', - Trash: 'trash', - TreeStructure: 'tree-structure', - Underline: 'underline', - Upgrade: 'upgrade', - Upload: 'upload', - Url: 'url', - UserIcon: 'user', - UsersIcon: 'users', - WarningIcon: 'warning', - Waves: 'waves', -}; - -export const resolveIconName = (name: string): IconName => { - const mapped = (ICON_NAME_RETRO_MAP as Record)[name]; - if (mapped) { - console.warn(`Icon name "${name}" is deprecated, use "${mapped}" instead`); - return mapped; - } - return name as IconName; -}; diff --git a/src/components/Assets/Logos/system/Logo.tsx b/src/components/Assets/Logos/system/Logo.tsx index 12b589d01..851a312bf 100644 --- a/src/components/Assets/Logos/system/Logo.tsx +++ b/src/components/Assets/Logos/system/Logo.tsx @@ -3,21 +3,23 @@ import { useTheme } from 'styled-components'; import { getFallbackThemeName } from '@/theme/theme.utils'; import { SvgImageElement } from '@/components/Icon/SvgImageElement'; import { LogoName, LogoProps } from './types'; +import { + createAssetResolver, + type AssetAlias, + type AssetDeprecatedName, +} from '@/components/Assets/config'; import LogosDark from './LogosDark'; import LogosLight from './LogosLight'; -// TODO: This is introducing complexity and more to maintain -// might be best to just deprecate (break change) instead of -// keeping deprecated names, it's small find and replace. -const resolveLogoName = (name: string): LogoName => { - if (name === 'c#') { - console.warn('Logo name "c#" is deprecated, use "c-sharp" instead'); - return 'c-sharp' as LogoName; - } - return name as LogoName; -}; +const resolveLogoName = createAssetResolver(); + +export { resolveLogoName }; + +export interface LogoPropsWithAliases extends Omit { + name: LogoName | AssetAlias | AssetDeprecatedName; +} -const Logo = ({ name, theme, size, ...props }: LogoProps) => { +const Logo = ({ name, theme, size, ...props }: LogoPropsWithAliases) => { const { name: themeName } = useTheme(); const resolvedName = resolveLogoName(name); const resolvedTheme = getFallbackThemeName(theme ?? themeName); diff --git a/src/components/Assets/Payments/MasterCard.tsx b/src/components/Assets/Payments/Mastercard.tsx similarity index 95% rename from src/components/Assets/Payments/MasterCard.tsx rename to src/components/Assets/Payments/Mastercard.tsx index 7e5cf41d4..616a02a93 100644 --- a/src/components/Assets/Payments/MasterCard.tsx +++ b/src/components/Assets/Payments/Mastercard.tsx @@ -1,6 +1,6 @@ import type { SVGAssetProps } from '@/types'; -const MasterCard = (props: SVGAssetProps) => ( +const Mastercard = (props: SVGAssetProps) => ( ( ); -export default MasterCard; +export default Mastercard; diff --git a/src/components/Assets/Payments/system/Payment.tsx b/src/components/Assets/Payments/system/Payment.tsx index 448e1f2e9..6f11366be 100644 --- a/src/components/Assets/Payments/system/Payment.tsx +++ b/src/components/Assets/Payments/system/Payment.tsx @@ -2,14 +2,29 @@ import { SVGAttributes } from 'react'; import { useTheme } from 'styled-components'; import { getFallbackThemeName } from '@/theme/theme.utils'; import { SvgImageElement } from '@/components/Icon/SvgImageElement'; -import { PaymentProps } from './types'; +import { PaymentName, PaymentProps } from './types'; +import { + createAssetResolver, + type AssetAlias, + type AssetDeprecatedName, +} from '@/components/Assets/config'; import PaymentsDark from './PaymentsDark'; import PaymentsLight from './PaymentsLight'; -const Payment = ({ name, theme, size, ...props }: PaymentProps) => { +const resolvePaymentName = createAssetResolver(); + +export { resolvePaymentName }; + +export interface PaymentPropsWithAliases extends Omit { + name: PaymentName | AssetAlias | AssetDeprecatedName; +} + +const Payment = ({ name, theme, size, ...props }: PaymentPropsWithAliases) => { const { name: themeName } = useTheme(); + const resolvedName = resolvePaymentName(name); const resolvedTheme = getFallbackThemeName(theme ?? themeName); - const Component = resolvedTheme === 'light' ? PaymentsLight[name] : PaymentsDark[name]; + const Component = + resolvedTheme === 'light' ? PaymentsLight[resolvedName] : PaymentsDark[resolvedName]; if (!Component) { return null; @@ -27,7 +42,7 @@ const Payment = ({ name, theme, size, ...props }: PaymentProps) => { as={ThemedPayment} $size={size} role="img" - aria-label={name} + aria-label={resolvedName} {...props} /> ); diff --git a/src/components/Assets/Payments/system/PaymentsDark.ts b/src/components/Assets/Payments/system/PaymentsDark.ts index b5b122269..71e2e59e8 100644 --- a/src/components/Assets/Payments/system/PaymentsDark.ts +++ b/src/components/Assets/Payments/system/PaymentsDark.ts @@ -6,7 +6,7 @@ */ import Amex from '../Amex'; -import MasterCard from '../MasterCard'; +import Mastercard from '../Mastercard'; import Paypal from '../Paypal'; import Visa from '../Visa'; import { PaymentName } from './types'; @@ -15,7 +15,7 @@ import type { ComponentType } from 'react'; const PaymentsDark: Record> = { amex: Amex, - mastercard: MasterCard, + mastercard: Mastercard, paypal: Paypal, visa: Visa, }; diff --git a/src/components/Assets/Payments/system/PaymentsLight.ts b/src/components/Assets/Payments/system/PaymentsLight.ts index f6eb94763..a4a4b3cbb 100644 --- a/src/components/Assets/Payments/system/PaymentsLight.ts +++ b/src/components/Assets/Payments/system/PaymentsLight.ts @@ -6,7 +6,7 @@ */ import Amex from '../Amex'; -import MasterCard from '../MasterCard'; +import Mastercard from '../Mastercard'; import Paypal from '../Paypal'; import Visa from '../Visa'; import { PaymentName } from './types'; @@ -15,7 +15,7 @@ import type { ComponentType } from 'react'; const PaymentsLight: Record> = { amex: Amex, - mastercard: MasterCard, + mastercard: Mastercard, paypal: Paypal, visa: Visa, }; diff --git a/src/components/Assets/config.ts b/src/components/Assets/config.ts new file mode 100644 index 000000000..dc8de9cb2 --- /dev/null +++ b/src/components/Assets/config.ts @@ -0,0 +1,244 @@ +export type AssetAliasMap = Record; +export type AssetAlias = keyof typeof ASSET_NAME_MAPPINGS.aliases; +export type AssetDeprecatedName = keyof typeof ASSET_NAME_MAPPINGS.deprecated; + +export const ASSET_NAME_MAPPINGS = { + aliases: { + 'c#': 'c-sharp', + } as AssetAliasMap, + + deprecated: { + Activity: 'activity', + Alarm: 'alarm', + ArrowDirections: 'arrow-directions', + ArrowDown: 'arrow-down', + ArrowLeft: 'arrow-left', + ArrowRight: 'arrow-right', + ArrowTriangle: 'arrow-triangle', + ArrowUp: 'arrow-up', + AuthApp: 'auth-app', + AuthSms: 'auth-sms', + Backups: 'backups', + BarChart: 'bar-chart', + Bell: 'bell', + Beta: 'beta', + Blog: 'blog', + Bold: 'bold', + Book: 'book', + Brackets: 'brackets', + Briefcase: 'briefcase', + Building: 'building', + BurgerMenu: 'burger-menu', + Calendar: 'calendar', + CalendarWithTime: 'calendar-with-time', + Cards: 'cards', + CellTower: 'cell-tower', + ChartArea: 'chart-area', + ChartBarHorizontal: 'chart-bar-horizontal', + ChartCloud: 'chart-cloud', + ChartDonut: 'chart-donut', + ChartHeatmap: 'chart-heatmap', + ChartScatter: 'chart-scatter', + ChartSquare: 'chart-square', + ChartStackedHorizontal: 'chart-stacked-horizontal', + ChartStackedVertical: 'chart-stacked-vertical', + ChatIcon: 'chat', + CheckIcon: 'check', + CheckInCircle: 'check-in-circle', + ChevronDown: 'chevron-down', + ChevronLeft: 'chevron-left', + ChevronRight: 'chevron-right', + ChevronUp: 'chevron-up', + Circle: 'circle', + Clock: 'clock', + Cloud: 'cloud', + CloudKeys: 'cloud-keys', + Code: 'code', + CodeInSquare: 'code-in-square', + Connect: 'connect', + ConnectAlt: 'connect-alt', + Console: 'console', + Copy: 'copy', + Cpu: 'cpu', + CreditCard: 'credit-card', + CrossIcon: 'cross', + Data: 'data', + DataLakes: 'data-lakes', + DatabaseIcon: 'database', + Disk: 'disk', + Display: 'display', + Document: 'document', + Dot: 'dot', + DotsHorizontal: 'dots-horizontal', + DotsTriangle: 'dots-triangle', + DotsVertical: 'dots-vertical', + DotsVerticalDouble: 'dots-vertical-double', + DoubleCheckIcon: 'double-check', + Download: 'download', + DownloadInCircle: 'download-in-circle', + Email: 'email', + Empty: 'empty', + Enter: 'enter', + Eye: 'eye', + EyeClosed: 'eye-closed', + FilterIcon: 'filter', + Fire: 'fire', + Flag: 'flag', + Flash: 'flash', + Flask: 'flask', + FolderClosed: 'folder-closed', + FolderOpen: 'folder-open', + Gear: 'gear', + Gift: 'gift', + GitMerge: 'git-merge', + Globe: 'globe', + Hexagon: 'hexagon', + HistoryIcon: 'history', + Home: 'home', + HorizontalLoading: 'horizontal-loading', + Http: 'http', + HttpMonitoring: 'http-monitoring', + InfoInCircleIcon: 'info-in-circle', + InformationIcon: 'information', + InsertRowIcon: 'insert-row', + Integrations: 'integrations', + Italic: 'italic', + Key: 'key', + Keys: 'keys', + Lifebuoy: 'lifebuoy', + LightBulb: 'light-bulb', + LightBulbOn: 'light-bulb-on', + Lightening: 'lightening', + LineInCircle: 'line-in-circle', + ListBulleted: 'list-bulleted', + ListNumbered: 'list-numbered', + Loading: 'loading', + LoadingAnimated: 'loading-animated', + Lock: 'lock', + MapPin: 'map-pin', + Mcp: 'mcp', + Metrics: 'metrics', + MetricsAlt: 'metrics-alt', + Minus: 'minus', + Moon: 'moon', + NoCloud: 'no-cloud', + Pause: 'pause', + Payment: 'payment', + Pencil: 'pencil', + PieChart: 'pie-chart', + Pipe: 'pipe', + Play: 'play', + PlayInCircle: 'play-in-circle', + Plug: 'plug', + Plus: 'plus', + Popout: 'popout', + PopoverArrow: 'popover-arrow', + PuzzlePiece: 'puzzle-piece', + Query: 'query', + Question: 'question', + Refresh: 'refresh', + ResizeArrowsHorizontal: 'resize-arrows-horizontal', + ResizeArrowsVertical: 'resize-arrows-vertical', + Rocket: 'rocket', + SandGlass: 'sand-glass', + Search: 'search', + Secure: 'secure', + Server: 'server', + Services: 'services', + Settings: 'settings', + Share: 'share', + ShareArrow: 'share-arrow', + ShareNetwork: 'share-network', + Sleep: 'sleep', + SlideIn: 'slide-in', + SlideOut: 'slide-out', + SortAltIcon: 'sort-alt', + SortIcon: 'sort', + Sparkle: 'sparkle', + Speaker: 'speaker', + Speed: 'speed', + Square: 'square', + Star: 'star', + Stop: 'stop', + Support: 'support', + Table: 'table', + Taxi: 'taxi', + TextSlash: 'text-slash', + ThumbsDown: 'thumbs-down', + ThumbsUp: 'thumbs-up', + Trash: 'trash', + TreeStructure: 'tree-structure', + Underline: 'underline', + Upgrade: 'upgrade', + Upload: 'upload', + Url: 'url', + UserIcon: 'user', + UsersIcon: 'users', + WarningIcon: 'warning', + Waves: 'waves', + + // Flag deprecations (from retroactiveNames.ts) + ae: 'united-arab-emirates', + au: 'australia', + br: 'brazil', + ca: 'canada', + ch: 'switzerland', + de: 'germany', + eu: 'european-union', + gb: 'great-britain', + hk: 'hong-kong', + id: 'indonesia', + ie: 'ireland', + il: 'israel', + in: 'india', + jp: 'japan', + nl: 'netherlands', + sg: 'singapore', + kr: 'south-korea', + sw: 'sweden', + uk: 'united-kingdom', + usa: 'united-states', + za: 'south-africa', + Australia: 'australia', + Brazil: 'brazil', + Canada: 'canada', + EuropeanUnion: 'european-union', + Germany: 'germany', + GreatBritain: 'great-britain', + HongKong: 'hong-kong', + India: 'india', + Indonesia: 'indonesia', + Ireland: 'ireland', + Israel: 'israel', + Japan: 'japan', + Netherlands: 'netherlands', + Singapore: 'singapore', + SouthAfrica: 'south-africa', + SouthKorea: 'south-korea', + Sweden: 'sweden', + Switzerland: 'switzerland', + UnitedArabEmirates: 'united-arab-emirates', + UnitedKingdom: 'united-kingdom', + UnitedStates: 'united-states', + } as AssetAliasMap, +} as const; + +export const resolveAssetName = (name: string): string => { + if (ASSET_NAME_MAPPINGS.aliases[name]) { + return ASSET_NAME_MAPPINGS.aliases[name]; + } + + if (ASSET_NAME_MAPPINGS.deprecated[name]) { + console.warn( + `Asset name "${name}" is deprecated, use "${ASSET_NAME_MAPPINGS.deprecated[name]}" instead` + ); + + return ASSET_NAME_MAPPINGS.deprecated[name]; + } + + return name; +}; + +export const createAssetResolver = () => { + return (name: string): T => resolveAssetName(name) as T; +};