refactor(frontend): remove redundant local aliases
cognitive committed
Apr 30, 2026 at 00:08 UTC
dbf1a760192d9a7acbadda6495f8f0ffacc6cd00
11 files changed
+50
-59
cmd/relay-server/frontend.go
+8
-12
@@ -95,7 +95,14 @@ func (f *Frontend) Handler() *http.ServeMux {
95
mux.HandleFunc(types.PathAssetsPrefix, func(w http.ResponseWriter, r *http.Request) {
96
f.ServeAsset(w, r, strings.TrimPrefix(r.URL.Path, "/"), "")
97
})
98
- for _, assetPath := range frontendRootAssetPaths() {
98
+ for _, assetPath := range []string{
99
+ "/favicon.ico",
100
+ "/favicon.svg",
101
+ "/favicon-96x96.png",
102
+ "/apple-touch-icon.png",
103
+ "/web-app-manifest-192x192.png",
104
+ "/web-app-manifest-512x512.png",
105
+ } {
106
mux.HandleFunc(assetPath, func(w http.ResponseWriter, r *http.Request) {
107
f.ServeAsset(w, r, strings.TrimPrefix(assetPath, "/"), "")
108
})
@@ -364,17 +371,6 @@ func getContentType(ext string) string {
371
return ""
372
}
373
367
-func frontendRootAssetPaths() []string {
368
- return []string{
369
- "/favicon.ico",
370
- "/favicon.svg",
371
- "/favicon-96x96.png",
372
- "/apple-touch-icon.png",
373
- "/web-app-manifest-192x192.png",
374
- "/web-app-manifest-512x512.png",
375
- }
376
-}
377
-
374
func serveInstallBinary(w http.ResponseWriter, r *http.Request) {
375
if r.Method != http.MethodGet && r.Method != http.MethodHead {
376
w.Header().Set("Allow", http.MethodGet+", "+http.MethodHead)
frontend/src/components/ServerCard.tsx
-2
@@ -59,14 +59,12 @@ export function ServerCard({
59
owner,
60
online,
61
firstSeen,
62
- dns: _dns,
62
navigationPath,
63
navigationState,
64
isFavorite = false,
65
onToggleFavorite,
66
showAdminControls = false,
67
identityKey,
69
- address: _address,
68
isBanned = false,
69
isApproved = false,
70
isDenied = false,
frontend/src/components/ServerListView.tsx
+4
-5
@@ -5,9 +5,9 @@ import { SearchBar } from "@/components/SearchBar";
5
import { ServerCard } from "@/components/ServerCard";
6
import { TagCombobox } from "@/components/TagCombobox";
7
import { TunnelCommandModal } from "@/components/TunnelCommandModal";
8
-import type { ClientServer } from "@/hooks/useServerList";
8
+import type { BaseServer } from "@/hooks/useList";
9
import type { AdminServer, ApprovalMode, UDPSettings, TCPPortSettings } from "@/hooks/useAdmin";
10
-import type { SortOption, StatusFilter } from "@/types/filters";
10
+import type { BanFilter, SortOption, StatusFilter } from "@/types/filters";
11
import { StatusSelect } from "@/components/select/StatusSelect";
12
import { BanStatusButtons } from "@/components/button/BanStatusButtons";
13
import { SortbySelect } from "@/components/select/SortbySelect";
@@ -23,8 +23,7 @@ import {
23
DialogTitle,
24
} from "@/components/ui/dialog";
25
26
-export type BanFilter = "all" | "banned" | "active";
27
-type ListServer = ClientServer | AdminServer;
26
+type ListServer = BaseServer | AdminServer;
27
28
interface RelayDomainResponse {
29
release_version?: string;
@@ -131,7 +130,7 @@ interface ServerListViewProps {
130
sortBy: SortOption;
131
selectedTags: string[];
132
availableTags: string[];
134
- filteredServers: ClientServer[] | AdminServer[];
133
+ filteredServers: BaseServer[] | AdminServer[];
134
favorites: string[];
135
onSearchChange: (value: string) => void;
136
onStatusChange: (value: StatusFilter) => void;
frontend/src/components/button/BanStatusButtons.tsx
+2
-2
@@ -1,8 +1,8 @@
1
-import { BanFilter } from "@/components/ServerListView";
1
+import type { BanFilter } from "@/types/filters";
2
import clsx from "clsx";
3
4
interface BanStatusButtonsProps {
5
- banFilter: string;
5
+ banFilter: BanFilter;
6
onBanFilterChange: (value: BanFilter) => void;
7
className?: string;
8
}
frontend/src/components/select/SortbySelect.tsx
+6
-3
@@ -5,11 +5,11 @@ import {
5
SelectTrigger,
6
SelectValue,
7
} from "@/components/ui/select";
8
-import { SortOption } from "@/types/filters";
8
+import type { SortOption } from "@/types/filters";
9
import clsx from "clsx";
10
11
interface SortbySelectProps {
12
- sortBy: string;
12
+ sortBy: SortOption;
13
onSortByChange: (value: SortOption) => void;
14
hideFiltersOnMobile?: boolean;
15
className?: string;
@@ -21,7 +21,10 @@ export const SortbySelect = ({
21
hideFiltersOnMobile,
22
className,
23
}: SortbySelectProps) => (
24
- <Select value={sortBy} onValueChange={onSortByChange}>
24
+ <Select
25
+ value={sortBy}
26
+ onValueChange={(value) => onSortByChange(value as SortOption)}
27
+ >
28
<SelectTrigger
29
className={clsx(
30
"w-37.5 h-10 border-border!",
frontend/src/components/select/StatusSelect.tsx
+6
-3
@@ -5,11 +5,11 @@ import {
5
SelectTrigger,
6
SelectValue,
7
} from "@/components/ui/select";
8
-import { StatusFilter } from "@/types/filters";
8
+import type { StatusFilter } from "@/types/filters";
9
import clsx from "clsx";
10
11
interface StatusSelectProps {
12
- status: string;
12
+ status: StatusFilter;
13
onStatusChange: (value: StatusFilter) => void;
14
hideFiltersOnMobile?: boolean;
15
className?: string;
@@ -21,7 +21,10 @@ export const StatusSelect = ({
21
hideFiltersOnMobile,
22
className,
23
}: StatusSelectProps) => (
24
- <Select value={status} onValueChange={onStatusChange}>
24
+ <Select
25
+ value={status}
26
+ onValueChange={(value) => onStatusChange(value as StatusFilter)}
27
+ >
28
<SelectTrigger
29
className={clsx(
30
"w-32.5 h-10 border-border!",
frontend/src/hooks/useAdmin.ts
+7
-9
@@ -1,7 +1,7 @@
1
import { useEffect, useMemo, useState } from "react";
2
import type { AdminLeaseData } from "@/hooks/useSSRData";
3
import { useList, type BaseServer } from "@/hooks/useList";
4
-import type { BanFilter } from "@/components/ServerListView";
4
+import type { BanFilter } from "@/types/filters";
5
import {
6
API_PATHS,
7
adminIPBanPath,
@@ -30,8 +30,6 @@ type AdminSnapshotResponse = {
30
tcp_port?: { enabled: boolean; max_leases: number };
31
};
32
33
-type LeaseActionResult = ApprovalModeResponse;
34
-
33
export interface AdminServer extends BaseServer {
34
identityKey: string;
35
address: string;
@@ -267,7 +265,7 @@ export function useAdmin() {
265
) => {
266
const identity = resolveLeaseIdentity(serverData, identityKey);
267
const method = enabled ? apiClient.post : apiClient.delete;
270
- await method<LeaseActionResult>(
268
+ await method<ApprovalModeResponse>(
269
adminLeasePath(identity.name, identity.address, action)
270
);
271
};
@@ -300,12 +298,12 @@ export function useAdmin() {
298
try {
299
await runAdminAction(async () => {
300
if (!Number.isFinite(normalizedBPS) || normalizedBPS <= 0) {
303
- await apiClient.delete<LeaseActionResult>(
301
+ await apiClient.delete<ApprovalModeResponse>(
302
adminLeasePath(identity.name, identity.address, "bps")
303
);
304
return;
305
}
308
- await apiClient.post<LeaseActionResult>(
306
+ await apiClient.post<ApprovalModeResponse>(
307
adminLeasePath(identity.name, identity.address, "bps"),
308
{ bps: normalizedBPS }
309
);
@@ -373,10 +371,10 @@ export function useAdmin() {
371
throw new Error("Missing IP address");
372
}
373
if (isBan) {
376
- await apiClient.post<LeaseActionResult>(adminIPBanPath(normalizedIP));
374
+ await apiClient.post<ApprovalModeResponse>(adminIPBanPath(normalizedIP));
375
return;
376
}
379
- await apiClient.delete<LeaseActionResult>(adminIPBanPath(normalizedIP));
377
+ await apiClient.delete<ApprovalModeResponse>(adminIPBanPath(normalizedIP));
378
});
379
380
const runBulkLeaseAction = async (identityKeys: string[], action: LeaseAction) => {
@@ -390,7 +388,7 @@ export function useAdmin() {
388
const results = await Promise.allSettled(
389
normalizedIdentityKeys.map((identityKey) => {
390
const identity = resolveLeaseIdentity(serverData, identityKey);
393
- return apiClient.post<LeaseActionResult>(
391
+ return apiClient.post<ApprovalModeResponse>(
392
adminLeasePath(identity.name, identity.address, action)
393
);
394
})
frontend/src/hooks/useServerList.ts
+2
-4
@@ -4,9 +4,7 @@ import type { PublicLeaseData } from "@/hooks/useSSRData";
4
import { useList, type BaseServer } from "@/hooks/useList";
5
import { parseLeaseMetadata } from "@/lib/metadata";
6
7
-export type ClientServer = BaseServer;
8
-
9
-function convertSSRDataToServers(ssrData: PublicLeaseData[]): ClientServer[] {
7
+function convertSSRDataToServers(ssrData: PublicLeaseData[]): BaseServer[] {
8
return ssrData.map((row) => {
9
const metadata = parseLeaseMetadata(row.Metadata);
10
const hostname = row.Hostname || "";
@@ -31,7 +29,7 @@ function convertSSRDataToServers(ssrData: PublicLeaseData[]): ClientServer[] {
29
export function useServerList() {
30
const ssrData = useSSRData();
31
34
- const servers: ClientServer[] = useMemo(
32
+ const servers: BaseServer[] = useMemo(
33
() => convertSSRDataToServers(ssrData),
34
[ssrData]
35
);
frontend/src/hooks/useTunnelCommand.ts
+9
-11
@@ -56,16 +56,6 @@ function nextTunnelNameShuffleKey(): string {
56
return `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
57
}
58
59
-function splitDisplayCommand(command: string, os: TunnelCommandOS) {
60
- const lines = command.split("\n");
61
- const installLineCount = os === "windows" ? 2 : 1;
62
-
63
- return {
64
- installBlock: lines.slice(0, installLineCount).join("\n"),
65
- runBlock: lines.slice(installLineCount).join("\n"),
66
- };
67
-}
68
-
59
interface TunnelCommandExtras {
60
relayUrls?: string[];
61
discovery?: boolean;
@@ -123,7 +113,15 @@ export function useTunnelCommand(extras: TunnelCommandExtras = {}) {
113
[commandOptions]
114
);
115
const { installBlock, runBlock } = useMemo(
126
- () => splitDisplayCommand(displayCommand, os),
116
+ () => {
117
+ const lines = displayCommand.split("\n");
118
+ const installLineCount = os === "windows" ? 2 : 1;
119
+
120
+ return {
121
+ installBlock: lines.slice(0, installLineCount).join("\n"),
122
+ runBlock: lines.slice(installLineCount).join("\n"),
123
+ };
124
+ },
125
[displayCommand, os]
126
);
127
frontend/src/lib/exposeName.ts
+5
-8
@@ -106,7 +106,11 @@ function normalizeExposeTarget(raw: string): string {
106
if (parsed.hostname === "") {
107
return candidate;
108
}
109
- return formatHostPort(parsed.hostname, parsed.port || "80");
109
+ const port = parsed.port || "80";
110
+ if (parsed.hostname.includes(":")) {
111
+ return `[${parsed.hostname}]:${port}`;
112
+ }
113
+ return `${parsed.hostname}:${port}`;
114
} catch {
115
return candidate;
116
}
@@ -188,10 +192,3 @@ function fnv1a32(bytes: Uint8Array, seed: number): number {
192
}
193
return hash >>> 0;
194
}
191
-
192
-function formatHostPort(hostname: string, port: string): string {
193
- if (hostname.includes(":")) {
194
- return `[${hostname}]:${port}`;
195
- }
196
- return `${hostname}:${port}`;
197
-}
frontend/src/types/filters.ts
+1
@@ -1,4 +1,5 @@
1
export type StatusFilter = "all" | "online" | "offline";
2
+export type BanFilter = "all" | "banned" | "active";
3
4
export type SortOption =
5
| "default"