mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-05 20:54:14 +00:00
refactor(frontend): extract fillStreamDefaults to shared helper
Move the network/security schema-default filler out of inbound-from-db.ts into stream-defaults.ts so other consumers can reuse it without dragging in the DBInbound-specific code path.
This commit is contained in:
parent
bb20cf506b
commit
66deec95ae
2 changed files with 71 additions and 69 deletions
|
|
@ -1,20 +1,9 @@
|
||||||
import type { Inbound } from '@/schemas/api/inbound';
|
import type { Inbound } from '@/schemas/api/inbound';
|
||||||
import { InboundSettingsSchema } from '@/schemas/protocols/inbound';
|
import { InboundSettingsSchema } from '@/schemas/protocols/inbound';
|
||||||
import {
|
|
||||||
GrpcStreamSettingsSchema,
|
|
||||||
HttpUpgradeStreamSettingsSchema,
|
|
||||||
HysteriaStreamSettingsSchema,
|
|
||||||
KcpStreamSettingsSchema,
|
|
||||||
TcpStreamSettingsSchema,
|
|
||||||
WsStreamSettingsSchema,
|
|
||||||
XHttpStreamSettingsSchema,
|
|
||||||
} from '@/schemas/protocols/stream';
|
|
||||||
import {
|
|
||||||
RealityStreamSettingsSchema,
|
|
||||||
TlsStreamSettingsSchema,
|
|
||||||
} from '@/schemas/protocols/security';
|
|
||||||
import { coerceInboundJsonField } from '@/models/dbinbound';
|
import { coerceInboundJsonField } from '@/models/dbinbound';
|
||||||
|
|
||||||
|
import { fillStreamDefaults } from './stream-defaults';
|
||||||
|
|
||||||
export interface DbInboundLike {
|
export interface DbInboundLike {
|
||||||
port: number;
|
port: number;
|
||||||
listen: string;
|
listen: string;
|
||||||
|
|
@ -31,62 +20,6 @@ export interface DbInboundLike {
|
||||||
total?: number;
|
total?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NETWORK_KEY_MAP = {
|
|
||||||
tcp: 'tcpSettings',
|
|
||||||
kcp: 'kcpSettings',
|
|
||||||
ws: 'wsSettings',
|
|
||||||
grpc: 'grpcSettings',
|
|
||||||
httpupgrade: 'httpupgradeSettings',
|
|
||||||
xhttp: 'xhttpSettings',
|
|
||||||
hysteria: 'hysteriaSettings',
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
type SchemaWithParse = { safeParse: (v: unknown) => { success: boolean; data?: unknown } };
|
|
||||||
|
|
||||||
function parseOrDefault(schema: SchemaWithParse, value: unknown): unknown {
|
|
||||||
const parsed = schema.safeParse(value ?? {});
|
|
||||||
if (parsed.success) return parsed.data;
|
|
||||||
const fallback = schema.safeParse({});
|
|
||||||
return fallback.success ? fallback.data : value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function networkSchemaFor(network: string): SchemaWithParse | null {
|
|
||||||
switch (network) {
|
|
||||||
case 'tcp': return TcpStreamSettingsSchema;
|
|
||||||
case 'kcp': return KcpStreamSettingsSchema;
|
|
||||||
case 'ws': return WsStreamSettingsSchema;
|
|
||||||
case 'grpc': return GrpcStreamSettingsSchema;
|
|
||||||
case 'httpupgrade': return HttpUpgradeStreamSettingsSchema;
|
|
||||||
case 'xhttp': return XHttpStreamSettingsSchema;
|
|
||||||
case 'hysteria': return HysteriaStreamSettingsSchema;
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function securitySchemaFor(security: string): { key: string; schema: SchemaWithParse } | null {
|
|
||||||
switch (security) {
|
|
||||||
case 'tls': return { key: 'tlsSettings', schema: TlsStreamSettingsSchema };
|
|
||||||
case 'reality': return { key: 'realitySettings', schema: RealityStreamSettingsSchema };
|
|
||||||
default: return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function fillStreamDefaults(stream: Record<string, unknown>): Record<string, unknown> {
|
|
||||||
const network = (stream.network as string | undefined) ?? 'tcp';
|
|
||||||
const security = (stream.security as string | undefined) ?? 'none';
|
|
||||||
const out: Record<string, unknown> = { ...stream, network, security };
|
|
||||||
const subKey = NETWORK_KEY_MAP[network as keyof typeof NETWORK_KEY_MAP];
|
|
||||||
const netSchema = networkSchemaFor(network);
|
|
||||||
if (subKey && netSchema) {
|
|
||||||
out[subKey] = parseOrDefault(netSchema, out[subKey]);
|
|
||||||
}
|
|
||||||
const sec = securitySchemaFor(security);
|
|
||||||
if (sec) {
|
|
||||||
out[sec.key] = parseOrDefault(sec.schema, out[sec.key]);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fillProtocolSettingsDefaults(protocol: string, settings: Record<string, unknown>): Record<string, unknown> {
|
function fillProtocolSettingsDefaults(protocol: string, settings: Record<string, unknown>): Record<string, unknown> {
|
||||||
const parsed = InboundSettingsSchema.safeParse({ protocol, settings });
|
const parsed = InboundSettingsSchema.safeParse({ protocol, settings });
|
||||||
if (parsed.success) {
|
if (parsed.success) {
|
||||||
|
|
|
||||||
69
frontend/src/lib/xray/stream-defaults.ts
Normal file
69
frontend/src/lib/xray/stream-defaults.ts
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
import {
|
||||||
|
GrpcStreamSettingsSchema,
|
||||||
|
HttpUpgradeStreamSettingsSchema,
|
||||||
|
HysteriaStreamSettingsSchema,
|
||||||
|
KcpStreamSettingsSchema,
|
||||||
|
TcpStreamSettingsSchema,
|
||||||
|
WsStreamSettingsSchema,
|
||||||
|
XHttpStreamSettingsSchema,
|
||||||
|
} from '@/schemas/protocols/stream';
|
||||||
|
import {
|
||||||
|
RealityStreamSettingsSchema,
|
||||||
|
TlsStreamSettingsSchema,
|
||||||
|
} from '@/schemas/protocols/security';
|
||||||
|
|
||||||
|
const NETWORK_KEY_MAP = {
|
||||||
|
tcp: 'tcpSettings',
|
||||||
|
kcp: 'kcpSettings',
|
||||||
|
ws: 'wsSettings',
|
||||||
|
grpc: 'grpcSettings',
|
||||||
|
httpupgrade: 'httpupgradeSettings',
|
||||||
|
xhttp: 'xhttpSettings',
|
||||||
|
hysteria: 'hysteriaSettings',
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
type SchemaWithParse = { safeParse: (v: unknown) => { success: boolean; data?: unknown } };
|
||||||
|
|
||||||
|
function parseOrDefault(schema: SchemaWithParse, value: unknown): unknown {
|
||||||
|
const parsed = schema.safeParse(value ?? {});
|
||||||
|
if (parsed.success) return parsed.data;
|
||||||
|
const fallback = schema.safeParse({});
|
||||||
|
return fallback.success ? fallback.data : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function networkSchemaFor(network: string): SchemaWithParse | null {
|
||||||
|
switch (network) {
|
||||||
|
case 'tcp': return TcpStreamSettingsSchema;
|
||||||
|
case 'kcp': return KcpStreamSettingsSchema;
|
||||||
|
case 'ws': return WsStreamSettingsSchema;
|
||||||
|
case 'grpc': return GrpcStreamSettingsSchema;
|
||||||
|
case 'httpupgrade': return HttpUpgradeStreamSettingsSchema;
|
||||||
|
case 'xhttp': return XHttpStreamSettingsSchema;
|
||||||
|
case 'hysteria': return HysteriaStreamSettingsSchema;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function securitySchemaFor(security: string): { key: string; schema: SchemaWithParse } | null {
|
||||||
|
switch (security) {
|
||||||
|
case 'tls': return { key: 'tlsSettings', schema: TlsStreamSettingsSchema };
|
||||||
|
case 'reality': return { key: 'realitySettings', schema: RealityStreamSettingsSchema };
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fillStreamDefaults(stream: Record<string, unknown>): Record<string, unknown> {
|
||||||
|
const network = (stream.network as string | undefined) ?? 'tcp';
|
||||||
|
const security = (stream.security as string | undefined) ?? 'none';
|
||||||
|
const out: Record<string, unknown> = { ...stream, network, security };
|
||||||
|
const subKey = NETWORK_KEY_MAP[network as keyof typeof NETWORK_KEY_MAP];
|
||||||
|
const netSchema = networkSchemaFor(network);
|
||||||
|
if (subKey && netSchema) {
|
||||||
|
out[subKey] = parseOrDefault(netSchema, out[subKey]);
|
||||||
|
}
|
||||||
|
const sec = securitySchemaFor(security);
|
||||||
|
if (sec) {
|
||||||
|
out[sec.key] = parseOrDefault(sec.schema, out[sec.key]);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue