Pulse/frontend-modern/src/utils/nodes.ts
2025-10-11 23:29:47 +00:00

62 lines
2.3 KiB
TypeScript

import type { Node } from '@/types/api';
type DisplayableNode = Pick<Node, 'name'> &
Partial<Pick<Node, 'displayName' | 'instance' | 'host'>>;
const sanitize = (value: string): string => value.trim().toLowerCase().replace(/[^a-z0-9]/g, '');
const escapeRegExp = (value: string): string => value.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\$&');
const extractHostname = (value: string): string => {
if (!value) return '';
const trimmed = value.trim();
const withoutProtocol = trimmed.replace(/^[a-z]+:\/\//i, '');
const [hostPart] = withoutProtocol.split('/');
return hostPart.replace(/:\d+$/, '');
};
export function getNodeDisplayName<T extends DisplayableNode>(node: T): string {
const display = typeof node.displayName === 'string' ? node.displayName.trim() : '';
if (display) return display;
const nameRaw = typeof node.name === 'string' ? node.name.trim() : '';
if (nameRaw) return nameRaw;
const hostRaw = typeof node.host === 'string' ? node.host.trim() : '';
const hostname = extractHostname(hostRaw);
if (hostname) return hostname;
const instance = typeof node.instance === 'string' ? node.instance.trim() : '';
if (instance) return instance;
return '';
}
export function hasAlternateDisplayName<T extends DisplayableNode>(node: T): boolean {
const displayRaw = typeof node.displayName === 'string' ? node.displayName.trim() : '';
if (!displayRaw) return false;
const nameRaw = typeof node.name === 'string' ? node.name.trim() : '';
if (!nameRaw) return false;
const displayLower = displayRaw.toLowerCase();
const nameLower = nameRaw.toLowerCase();
if (displayLower === nameLower) return false;
// Normalize values so cosmetic punctuation/domains do not trigger duplicates in the UI
const sanitizedDisplay = sanitize(displayRaw);
const sanitizedName = sanitize(nameRaw);
if (sanitizedDisplay === sanitizedName) return false;
// Catch cases where the raw display text already embeds the node name (e.g. "Friendly (node)")
const namePattern = new RegExp(`\\b${escapeRegExp(nameLower)}\\b`, 'i');
if (namePattern.test(displayLower)) return false;
const [firstLabel = ''] = displayLower.split('.');
const sanitizedFirstLabel = sanitize(firstLabel);
if (sanitizedFirstLabel === sanitizedName) return false;
return true;
}