refactor(frontend): lift outbound option dictionaries to schemas/primitives

Adds schemas/primitives/options.ts with UTLS_FINGERPRINT, ALPN_OPTION,
SNIFFING_OPTION, USERS_SECURITY, MODE_OPTION (all identical between
models/inbound.ts and models/outbound.ts) plus the outbound-only
WireguardDomainStrategy, Address_Port_Strategy, and DNSRuleActions.

OutboundFormModal now pulls 9 consts from primitives. Only `Outbound`
(the class) and `SSMethods` (whose inbound/outbound versions diverge by
2 legacy aliases — keep the picker open for the Pattern A rewrite) still
come from @/models/outbound.

Drops three stale `as string[]` casts on what are now readonly tuples.
This commit is contained in:
MHSanaei
2026-05-26 01:11:51 +02:00
parent 40ca58d42e
commit 2d74dbe7ad
3 changed files with 69 additions and 7 deletions

View File

@@ -18,10 +18,9 @@ import { SyncOutlined, PlusOutlined, MinusOutlined, DeleteOutlined } from '@ant-
import { Wireguard } from '@/utils';
import InputAddon from '@/components/InputAddon';
import { Outbound, SSMethods } from '@/models/outbound';
import {
Outbound,
Protocols,
SSMethods,
OutboundProtocols as Protocols,
TLS_FLOW_CONTROL,
UTLS_FINGERPRINT,
ALPN_OPTION,
@@ -32,7 +31,7 @@ import {
Address_Port_Strategy,
MODE_OPTION,
DNSRuleActions,
} from '@/models/outbound';
} from '@/schemas/primitives';
import FinalMaskForm from '@/components/FinalMaskForm';
import JsonEditor from '@/components/JsonEditor';
import { OutboundTagSchema } from '@/schemas/xray';
@@ -494,7 +493,7 @@ function FreedomFields({ ob, refresh }: FieldProps) {
<Select
value={ob.settings.domainStrategy}
onChange={(v) => { ob.settings.domainStrategy = v; refresh(); }}
options={(OutboundDomainStrategies as string[]).map((s) => ({ value: s, label: s }))}
options={OutboundDomainStrategies.map((s) => ({ value: s, label: s }))}
/>
</Form.Item>
<Form.Item label="Redirect">
@@ -722,7 +721,7 @@ function DnsFields({ ob, refresh, t }: TFieldProps) {
<Select
value={rule.action}
onChange={(v) => { rule.action = v; refresh(); }}
options={(DNSRuleActions as string[]).map((a) => ({ value: a, label: a }))}
options={DNSRuleActions.map((a) => ({ value: a, label: a }))}
/>
</Form.Item>
<Form.Item label="QType">
@@ -775,7 +774,7 @@ function WireguardFields({ ob, refresh, regenerate, t }: TFieldProps & { regener
<Select
value={ob.settings.domainStrategy || ''}
onChange={(v) => { ob.settings.domainStrategy = v; refresh(); }}
options={['', ...(WireguardDomainStrategy as string[])].map((x) => ({ value: x, label: x || `(${t('none')})` }))}
options={['', ...WireguardDomainStrategy].map((x) => ({ value: x, label: x || `(${t('none')})` }))}
/>
</Form.Item>
<Form.Item label="MTU">

View File

@@ -3,3 +3,4 @@ export * from './protocol';
export * from './outbound-protocol';
export * from './sniffing';
export * from './flow';
export * from './options';

View File

@@ -0,0 +1,62 @@
export const UTLS_FINGERPRINT = Object.freeze({
UTLS_CHROME: 'chrome',
UTLS_FIREFOX: 'firefox',
UTLS_SAFARI: 'safari',
UTLS_IOS: 'ios',
UTLS_android: 'android',
UTLS_EDGE: 'edge',
UTLS_360: '360',
UTLS_QQ: 'qq',
UTLS_RANDOM: 'random',
UTLS_RANDOMIZED: 'randomized',
UTLS_RONDOMIZEDNOALPN: 'randomizednoalpn',
UTLS_UNSAFE: 'unsafe',
});
export const ALPN_OPTION = Object.freeze({
H3: 'h3',
H2: 'h2',
HTTP1: 'http/1.1',
});
export const SNIFFING_OPTION = Object.freeze({
HTTP: 'http',
TLS: 'tls',
QUIC: 'quic',
FAKEDNS: 'fakedns',
});
export const USERS_SECURITY = Object.freeze({
AES_128_GCM: 'aes-128-gcm',
CHACHA20_POLY1305: 'chacha20-poly1305',
AUTO: 'auto',
NONE: 'none',
ZERO: 'zero',
});
export const MODE_OPTION = Object.freeze({
AUTO: 'auto',
PACKET_UP: 'packet-up',
STREAM_UP: 'stream-up',
STREAM_ONE: 'stream-one',
});
export const WireguardDomainStrategy = Object.freeze([
'ForceIP',
'ForceIPv4',
'ForceIPv4v6',
'ForceIPv6',
'ForceIPv6v4',
] as const);
export const Address_Port_Strategy = Object.freeze({
NONE: 'none',
SrvPortOnly: 'srvportonly',
SrvAddressOnly: 'srvaddressonly',
SrvPortAndAddress: 'srvportandaddress',
TxtPortOnly: 'txtportonly',
TxtAddressOnly: 'txtaddressonly',
TxtPortAndAddress: 'txtportandaddress',
});
export const DNSRuleActions = Object.freeze(['direct', 'drop', 'reject', 'hijack'] as const);