From 4ce2503c1ebddc01119394627be88c46693959a2 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Tue, 26 May 2026 00:51:52 +0200 Subject: [PATCH] refactor(frontend): lift Protocols + TLS_FLOW_CONTROL consts to schemas/primitives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 4b. The Protocols and TLS_FLOW_CONTROL enums on models/inbound.ts were dragging five page files into that 3,300-line module just to read literal string constants. Lifting them to schemas/primitives lets those pages drop the @/models/inbound import entirely. - schemas/primitives/protocol.ts now exports a Protocols const map alongside the existing ProtocolSchema. TUN stays in the const for parity (legacy panel deployments may have saved TUN inbounds) even though the Go validator no longer accepts it as a new write. - schemas/primitives/flow.ts now exports TLS_FLOW_CONTROL. The empty-string default isn't keyed because the legacy never had a NONE entry — call sites compare against the two real flow values. Updated five consumers: - useInbounds.ts: TRACKED_PROTOCOLS now annotated readonly string[] so .includes(string) keeps narrowing through the array literal - QrCodeModal.tsx, InboundInfoModal.tsx: Protocols - ClientFormModal.tsx, ClientBulkAddModal.tsx: TLS_FLOW_CONTROL Suite: 89 tests across 8 files; typecheck + lint clean. models/inbound.ts is now imported by: - InboundFormModal.tsx (heavy use of Inbound class + getSettings) - test/inbound-link.test.ts + test/shadow.test.ts + test/headers.test.ts (intentional — these are parity tests against the legacy class) OutboundFormModal still imports from models/outbound. Both form modals are the multi-day Pattern A rewrites the plan scopes separately. --- .../src/pages/clients/ClientBulkAddModal.tsx | 2 +- .../src/pages/clients/ClientFormModal.tsx | 2 +- .../src/pages/inbounds/InboundInfoModal.tsx | 2 +- frontend/src/pages/inbounds/QrCodeModal.tsx | 2 +- frontend/src/pages/inbounds/useInbounds.ts | 4 ++-- frontend/src/schemas/primitives/flow.ts | 8 ++++++++ frontend/src/schemas/primitives/protocol.ts | 20 +++++++++++++++++++ 7 files changed, 34 insertions(+), 6 deletions(-) diff --git a/frontend/src/pages/clients/ClientBulkAddModal.tsx b/frontend/src/pages/clients/ClientBulkAddModal.tsx index 2b16378b..d4c9c537 100644 --- a/frontend/src/pages/clients/ClientBulkAddModal.tsx +++ b/frontend/src/pages/clients/ClientBulkAddModal.tsx @@ -6,7 +6,7 @@ import dayjs from 'dayjs'; import type { Dayjs } from 'dayjs'; import { HttpUtil, RandomUtil, SizeFormatter } from '@/utils'; -import { TLS_FLOW_CONTROL } from '@/models/inbound'; +import { TLS_FLOW_CONTROL } from '@/schemas/primitives'; import DateTimePicker from '@/components/DateTimePicker'; import type { InboundOption } from '@/hooks/useClients'; import { ClientBulkAddFormSchema, type ClientBulkAddFormValues } from '@/schemas/client'; diff --git a/frontend/src/pages/clients/ClientFormModal.tsx b/frontend/src/pages/clients/ClientFormModal.tsx index a7a65e3d..1f2a4bdb 100644 --- a/frontend/src/pages/clients/ClientFormModal.tsx +++ b/frontend/src/pages/clients/ClientFormModal.tsx @@ -19,7 +19,7 @@ import type { Dayjs } from 'dayjs'; import { HttpUtil, RandomUtil } from '@/utils'; import DateTimePicker from '@/components/DateTimePicker'; -import { TLS_FLOW_CONTROL } from '@/models/inbound'; +import { TLS_FLOW_CONTROL } from '@/schemas/primitives'; import type { ClientRecord, InboundOption } from '@/hooks/useClients'; import { ClientFormSchema, ClientCreateFormSchema } from '@/schemas/client'; import './ClientFormModal.css'; diff --git a/frontend/src/pages/inbounds/InboundInfoModal.tsx b/frontend/src/pages/inbounds/InboundInfoModal.tsx index 6f3a0599..366e445d 100644 --- a/frontend/src/pages/inbounds/InboundInfoModal.tsx +++ b/frontend/src/pages/inbounds/InboundInfoModal.tsx @@ -12,7 +12,7 @@ import { ClipboardManager, FileManager, } from '@/utils'; -import { Protocols } from '@/models/inbound'; +import { Protocols } from '@/schemas/primitives'; import InfinityIcon from '@/components/InfinityIcon'; import { useDatepicker } from '@/hooks/useDatepicker'; import type { SubSettings } from './useInbounds'; diff --git a/frontend/src/pages/inbounds/QrCodeModal.tsx b/frontend/src/pages/inbounds/QrCodeModal.tsx index 720944e5..22ba564c 100644 --- a/frontend/src/pages/inbounds/QrCodeModal.tsx +++ b/frontend/src/pages/inbounds/QrCodeModal.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'; import { Collapse, Modal } from 'antd'; import type { CollapseProps } from 'antd'; -import { Protocols } from '@/models/inbound'; +import { Protocols } from '@/schemas/primitives'; import QrPanel from './QrPanel'; import type { SubSettings } from './useInbounds'; diff --git a/frontend/src/pages/inbounds/useInbounds.ts b/frontend/src/pages/inbounds/useInbounds.ts index faf57801..c4a6abb7 100644 --- a/frontend/src/pages/inbounds/useInbounds.ts +++ b/frontend/src/pages/inbounds/useInbounds.ts @@ -4,7 +4,7 @@ import { useQuery, useQueryClient } from '@tanstack/react-query'; import { HttpUtil } from '@/utils'; import { parseMsg } from '@/utils/zodValidate'; import { DBInbound } from '@/models/dbinbound'; -import { Protocols } from '@/models/inbound'; +import { Protocols } from '@/schemas/primitives'; import { setDatepicker } from '@/hooks/useDatepicker'; import { keys } from '@/api/queryKeys'; import { SlimInboundListSchema, LastOnlineMapSchema, InboundDetailSchema } from '@/schemas/inbound'; @@ -31,7 +31,7 @@ interface ClientRollup { comments: Map; } -const TRACKED_PROTOCOLS = [ +const TRACKED_PROTOCOLS: readonly string[] = [ Protocols.VMESS, Protocols.VLESS, Protocols.TROJAN, diff --git a/frontend/src/schemas/primitives/flow.ts b/frontend/src/schemas/primitives/flow.ts index faf17eab..c9449445 100644 --- a/frontend/src/schemas/primitives/flow.ts +++ b/frontend/src/schemas/primitives/flow.ts @@ -6,3 +6,11 @@ export const FlowSchema = z.enum([ 'xtls-rprx-vision-udp443', ]); export type Flow = z.infer; + +// Const map matching the legacy models/inbound.ts `TLS_FLOW_CONTROL` +// export. The empty-string default isn't keyed here — the legacy never +// carried a NONE key and call sites compare against the two real flows. +export const TLS_FLOW_CONTROL = Object.freeze({ + VISION: 'xtls-rprx-vision', + VISION_UDP443: 'xtls-rprx-vision-udp443', +}) satisfies Record>; diff --git a/frontend/src/schemas/primitives/protocol.ts b/frontend/src/schemas/primitives/protocol.ts index e77b0653..9b619680 100644 --- a/frontend/src/schemas/primitives/protocol.ts +++ b/frontend/src/schemas/primitives/protocol.ts @@ -13,3 +13,23 @@ export const ProtocolSchema = z.enum([ 'tunnel', ]); export type Protocol = z.infer; + +// Const map matching the legacy models/inbound.ts `Protocols` export so +// call sites can swap the import without touching `Protocols.VLESS`-style +// references throughout the codebase. Frozen so downstream code can't +// mutate the dispatch table. TUN is kept here for parity even though the +// Go backend's validator no longer accepts it — existing panel deployments +// may still have TUN inbounds saved that we want to render. +export const Protocols = Object.freeze({ + VMESS: 'vmess', + VLESS: 'vless', + TROJAN: 'trojan', + SHADOWSOCKS: 'shadowsocks', + WIREGUARD: 'wireguard', + HYSTERIA: 'hysteria', + HYSTERIA2: 'hysteria2', + HTTP: 'http', + MIXED: 'mixed', + TUNNEL: 'tunnel', + TUN: 'tun', +});