Prechádzať zdrojové kódy

refactor(frontend): swap InboundsPage clone fallback off Inbound.Settings.getSettings

First Step 4 call-site swap. createDefaultInboundSettings(protocol) lands
in lib/xray/inbound-defaults — a protocol-aware dispatch over the 10
per-protocol settings factories already in this module. Returns a Zod-
parsable plain object instead of a class instance, so callers that just
need the wire-shape JSON can drop the class hierarchy without touching
the broader form modals.

InboundsPage's clone path used Inbound.Settings.getSettings(p).toString()
as the fallback when settings JSON parsing failed. That's now
createDefaultInboundSettings + JSON.stringify, with a final '{}' guard
for unknown protocols (legacy returned null and .toString() crashed —
we just emit empty settings instead). The Inbound import on this file
is now unused and removed.

The 2 remaining getSettings call sites in InboundFormModal aren't safe
to swap in isolation — the form mutates the returned class instance
through methods like .addClient() and .toJson() across ~2000 lines of
JSX. Those land with the full Pattern A rewrite of InboundFormModal,
which the plan budgets at multiple days on its own.

Suite: 89 tests across 8 files; typecheck + lint clean.
MHSanaei 22 hodín pred
rodič
commit
bd03f1a117

+ 33 - 0
frontend/src/lib/xray/inbound-defaults.ts

@@ -225,3 +225,36 @@ export function createDefaultWireguardInboundSettings(
     noKernelTun: seed.noKernelTun ?? false,
   };
 }
+
+// Protocol-aware dispatch over every inbound-settings factory. Mirrors
+// the legacy `Inbound.Settings.getSettings(protocol)` dispatcher, but
+// returns a plain Zod-parsable object instead of a class instance.
+// Callers swapping off the class hierarchy use this in place of
+// `getSettings(p)` + `.toJson()`.
+export type AnyInboundSettings =
+  | VlessInboundSettings
+  | VmessInboundSettings
+  | TrojanInboundSettings
+  | ShadowsocksInboundSettings
+  | HysteriaInboundSettings
+  | Hysteria2InboundSettings
+  | HttpInboundSettings
+  | MixedInboundSettings
+  | TunnelInboundSettings
+  | WireguardInboundSettings;
+
+export function createDefaultInboundSettings(protocol: string): AnyInboundSettings | null {
+  switch (protocol) {
+    case 'vless':       return createDefaultVlessInboundSettings();
+    case 'vmess':       return createDefaultVmessInboundSettings();
+    case 'trojan':      return createDefaultTrojanInboundSettings();
+    case 'shadowsocks': return createDefaultShadowsocksInboundSettings();
+    case 'hysteria':    return createDefaultHysteriaInboundSettings();
+    case 'hysteria2':   return createDefaultHysteria2InboundSettings();
+    case 'http':        return createDefaultHttpInboundSettings();
+    case 'mixed':       return createDefaultMixedInboundSettings();
+    case 'tunnel':      return createDefaultTunnelInboundSettings();
+    case 'wireguard':   return createDefaultWireguardInboundSettings();
+    default:            return null;
+  }
+}

+ 3 - 2
frontend/src/pages/inbounds/InboundsPage.tsx

@@ -20,7 +20,7 @@ import {
 } from '@ant-design/icons';
 
 import { HttpUtil, SizeFormatter, RandomUtil } from '@/utils';
-import { Inbound } from '@/models/inbound';
+import { createDefaultInboundSettings } from '@/lib/xray/inbound-defaults';
 import { coerceInboundJsonField, type DBInbound } from '@/models/dbinbound';
 import { useTheme } from '@/hooks/useTheme';
 import { useMediaQuery } from '@/hooks/useMediaQuery';
@@ -354,7 +354,8 @@ export default function InboundsPage() {
           raw.clients = [];
           clonedSettings = JSON.stringify(raw);
         } catch {
-          clonedSettings = Inbound.Settings.getSettings(baseInbound.protocol).toString();
+          const fallback = createDefaultInboundSettings(baseInbound.protocol);
+          clonedSettings = fallback ? JSON.stringify(fallback, null, 2) : '{}';
         }
         const data = {
           up: 0,