refactor(frontend): port models/outbound to TypeScript (hybrid typing)

Phase 4 of the JS→TS migration: rename outbound.js to outbound.ts and
make it compile under strict mode with a minimal hybrid type pass.

- Enum-like constants kept as typed objects (Protocols, SSMethods, …)
- Top-level DNS helpers strictly typed
- CommonClass gets [key: string]: any so all subclasses can keep their
  loose this.foo = bar assignments without per-field declarations
- Constructor / fromJson / toJson signatures typed as any to preserve
  the prior JS contract used by consumers and parsers
- Outbound declares static fields for the dynamically-attached Settings
  subclasses (Settings, FreedomSettings, VmessSettings, …)
- urlParams.get() results that feed parseInt now use the non-null
  assertion since the surrounding has() check already guards them
- File-level eslint-disable for no-explicit-any/no-var/prefer-const to
  keep the JS-derived code building without churn
This commit is contained in:
MHSanaei 2026-05-25 00:48:10 +02:00
parent 203d6339ea
commit f96fa7a849
No known key found for this signature in database
GPG key ID: 7E4060F2FBE5AB7A

View file

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any, no-var, prefer-const */
import { ObjectUtil, Base64, Wireguard } from '@/utils'; import { ObjectUtil, Base64, Wireguard } from '@/utils';
export const Protocols = { export const Protocols = {
@ -109,30 +110,30 @@ export const Address_Port_Strategy = {
export const DNSRuleActions = ['direct', 'drop', 'reject', 'hijack']; export const DNSRuleActions = ['direct', 'drop', 'reject', 'hijack'];
export function normalizeDNSRuleField(value) { export function normalizeDNSRuleField(value: any): string {
if (value === null || value === undefined) { if (value === null || value === undefined) {
return ''; return '';
} }
if (Array.isArray(value)) { if (Array.isArray(value)) {
return value.map(item => item.toString().trim()).filter(item => item.length > 0).join(','); return value.map((item: any) => item.toString().trim()).filter((item: any) => item.length > 0).join(',');
} }
return value.toString().trim(); return value.toString().trim();
} }
export function normalizeDNSRuleAction(action) { export function normalizeDNSRuleAction(action: any): string {
action = ObjectUtil.isEmpty(action) ? 'direct' : action.toString().toLowerCase().trim(); action = ObjectUtil.isEmpty(action) ? 'direct' : action.toString().toLowerCase().trim();
return DNSRuleActions.includes(action) ? action : 'direct'; return DNSRuleActions.includes(action) ? action : 'direct';
} }
export function parseLegacyDNSBlockTypes(blockTypes) { export function parseLegacyDNSBlockTypes(blockTypes: any): number[] {
if (blockTypes === null || blockTypes === undefined || blockTypes === '') { if (blockTypes === null || blockTypes === undefined || blockTypes === '') {
return []; return [];
} }
if (Array.isArray(blockTypes)) { if (Array.isArray(blockTypes)) {
return blockTypes return blockTypes
.map(item => Number(item)) .map((item: any) => Number(item))
.filter(item => Number.isInteger(item) && item >= 0 && item <= 65535); .filter((item: any) => Number.isInteger(item) && item >= 0 && item <= 65535);
} }
if (typeof blockTypes === 'number') { if (typeof blockTypes === 'number') {
@ -142,13 +143,13 @@ export function parseLegacyDNSBlockTypes(blockTypes) {
return blockTypes return blockTypes
.toString() .toString()
.split(',') .split(',')
.map(item => item.trim()) .map((item: any) => item.trim())
.filter(item => /^\d+$/.test(item)) .filter((item: any) => /^\d+$/.test(item))
.map(item => Number(item)) .map((item: any) => Number(item))
.filter(item => item >= 0 && item <= 65535); .filter((item: any) => item >= 0 && item <= 65535);
} }
export function buildLegacyDNSRules(nonIPQuery, blockTypes) { export function buildLegacyDNSRules(nonIPQuery: any, blockTypes: any): any[] {
const mode = ['reject', 'drop', 'skip'].includes(nonIPQuery) ? nonIPQuery : 'reject'; const mode = ['reject', 'drop', 'skip'].includes(nonIPQuery) ? nonIPQuery : 'reject';
const rules = []; const rules = [];
const parsedBlockTypes = parseLegacyDNSBlockTypes(blockTypes); const parsedBlockTypes = parseLegacyDNSBlockTypes(blockTypes);
@ -163,9 +164,9 @@ export function buildLegacyDNSRules(nonIPQuery, blockTypes) {
return rules; return rules;
} }
export function getDNSRulesFromJson(json = {}) { export function getDNSRulesFromJson(json: any = {}): any[] {
if (Array.isArray(json.rules) && json.rules.length > 0) { if (Array.isArray(json.rules) && json.rules.length > 0) {
return json.rules.map(rule => Outbound.DNSRule.fromJson(rule)); return json.rules.map((rule: any) => Outbound.DNSRule.fromJson(rule));
} }
if (json.nonIPQuery !== undefined || json.blockTypes !== undefined) { if (json.nonIPQuery !== undefined || json.blockTypes !== undefined) {
@ -189,20 +190,21 @@ Object.freeze(Address_Port_Strategy);
Object.freeze(DNSRuleActions); Object.freeze(DNSRuleActions);
export class CommonClass { export class CommonClass {
[key: string]: any;
static toJsonArray(arr) { static toJsonArray(arr: any[]): any[] {
return arr.map(obj => obj.toJson()); return arr.map(obj => obj.toJson());
} }
static fromJson() { static fromJson(..._args: any[]): any {
return new CommonClass(); return new CommonClass();
} }
toJson() { toJson(): any {
return this; return this;
} }
toString(format = true) { toString(format: boolean = true): string {
return format ? JSON.stringify(this.toJson(), null, 2) : JSON.stringify(this.toJson()); return format ? JSON.stringify(this.toJson(), null, 2) : JSON.stringify(this.toJson());
} }
} }
@ -225,7 +227,7 @@ export class ReverseSniffing extends CommonClass {
this.domainsExcluded = Array.isArray(domainsExcluded) ? domainsExcluded : []; this.domainsExcluded = Array.isArray(domainsExcluded) ? domainsExcluded : [];
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
if (!json || Object.keys(json).length === 0) { if (!json || Object.keys(json).length === 0) {
return new ReverseSniffing(); return new ReverseSniffing();
} }
@ -252,14 +254,14 @@ export class ReverseSniffing extends CommonClass {
} }
export class TcpStreamSettings extends CommonClass { export class TcpStreamSettings extends CommonClass {
constructor(type = 'none', host, path) { constructor(type: any = 'none', host?: any, path?: any) {
super(); super();
this.type = type; this.type = type;
this.host = host; this.host = host;
this.path = path; this.path = path;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
let header = json.header; let header = json.header;
if (!header) return new TcpStreamSettings(); if (!header) return new TcpStreamSettings();
if (header.type == 'http' && header.request) { if (header.type == 'http' && header.request) {
@ -305,7 +307,7 @@ export class KcpStreamSettings extends CommonClass {
this.maxSendingWindow = maxSendingWindow; this.maxSendingWindow = maxSendingWindow;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new KcpStreamSettings( return new KcpStreamSettings(
json.mtu, json.mtu,
json.tti, json.tti,
@ -341,7 +343,7 @@ export class WsStreamSettings extends CommonClass {
this.heartbeatPeriod = heartbeatPeriod; this.heartbeatPeriod = heartbeatPeriod;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new WsStreamSettings( return new WsStreamSettings(
json.path, json.path,
json.host, json.host,
@ -370,7 +372,7 @@ export class GrpcStreamSettings extends CommonClass {
this.multiMode = multiMode; this.multiMode = multiMode;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new GrpcStreamSettings(json.serviceName, json.authority, json.multiMode); return new GrpcStreamSettings(json.serviceName, json.authority, json.multiMode);
} }
@ -390,7 +392,7 @@ export class HttpUpgradeStreamSettings extends CommonClass {
this.host = host; this.host = host;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new HttpUpgradeStreamSettings( return new HttpUpgradeStreamSettings(
json.path, json.path,
json.host, json.host,
@ -414,10 +416,10 @@ export class HttpUpgradeStreamSettings extends CommonClass {
export class xHTTPStreamSettings extends CommonClass { export class xHTTPStreamSettings extends CommonClass {
constructor( constructor(
// Bidirectional — must match the inbound side // Bidirectional — must match the inbound side
path = '/', path: any = '/',
host = '', host: any = '',
mode = '', mode: any = '',
xPaddingBytes = "100-1000", xPaddingBytes: any = "100-1000",
xPaddingObfsMode = false, xPaddingObfsMode = false,
xPaddingKey = '', xPaddingKey = '',
xPaddingHeader = '', xPaddingHeader = '',
@ -429,9 +431,9 @@ export class xHTTPStreamSettings extends CommonClass {
seqKey = '', seqKey = '',
uplinkDataPlacement = '', uplinkDataPlacement = '',
uplinkDataKey = '', uplinkDataKey = '',
scMaxEachPostBytes = "1000000", scMaxEachPostBytes: any = "1000000",
// Client-side only // Client-side only
headers = [], headers: any[] = [],
uplinkHTTPMethod = '', uplinkHTTPMethod = '',
uplinkChunkSize = 0, uplinkChunkSize = 0,
noGRPCHeader = false, noGRPCHeader = false,
@ -475,17 +477,17 @@ export class xHTTPStreamSettings extends CommonClass {
this.enableXmux = enableXmux; this.enableXmux = enableXmux;
} }
addHeader(name, value) { addHeader(name: any, value: any): void {
this.headers.push({ name: name, value: value }); this.headers.push({ name: name, value: value });
} }
removeHeader(index) { removeHeader(index: number): void {
this.headers.splice(index, 1); this.headers.splice(index, 1);
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
const headersInput = json.headers; const headersInput = json.headers;
let headers = []; let headers: any[] = [];
if (Array.isArray(headersInput)) { if (Array.isArray(headersInput)) {
headers = headersInput; headers = headersInput;
} else if (headersInput && typeof headersInput === 'object') { } else if (headersInput && typeof headersInput === 'object') {
@ -524,7 +526,7 @@ export class xHTTPStreamSettings extends CommonClass {
toJson() { toJson() {
// Upstream expects headers as a {name: value} map, not a list of entries. // Upstream expects headers as a {name: value} map, not a list of entries.
const headersMap = {}; const headersMap: any = {};
if (Array.isArray(this.headers)) { if (Array.isArray(this.headers)) {
for (const h of this.headers) { for (const h of this.headers) {
if (h && h.name) headersMap[h.name] = h.value || ''; if (h && h.name) headersMap[h.name] = h.value || '';
@ -566,9 +568,9 @@ export class xHTTPStreamSettings extends CommonClass {
export class TlsStreamSettings extends CommonClass { export class TlsStreamSettings extends CommonClass {
constructor( constructor(
serverName = '', serverName: any = '',
alpn = [], alpn: any[] = [],
fingerprint = '', fingerprint: any = '',
echConfigList = '', echConfigList = '',
verifyPeerCertByName = '', verifyPeerCertByName = '',
pinnedPeerCertSha256 = '', pinnedPeerCertSha256 = '',
@ -582,7 +584,7 @@ export class TlsStreamSettings extends CommonClass {
this.pinnedPeerCertSha256 = pinnedPeerCertSha256; this.pinnedPeerCertSha256 = pinnedPeerCertSha256;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new TlsStreamSettings( return new TlsStreamSettings(
json.serverName, json.serverName,
json.alpn, json.alpn,
@ -607,12 +609,12 @@ export class TlsStreamSettings extends CommonClass {
export class RealityStreamSettings extends CommonClass { export class RealityStreamSettings extends CommonClass {
constructor( constructor(
publicKey = '', publicKey: any = '',
fingerprint = '', fingerprint: any = '',
serverName = '', serverName: any = '',
shortId = '', shortId: any = '',
spiderX = '', spiderX: any = '',
mldsa65Verify = '' mldsa65Verify: any = ''
) { ) {
super(); super();
this.publicKey = publicKey; this.publicKey = publicKey;
@ -622,7 +624,7 @@ export class RealityStreamSettings extends CommonClass {
this.spiderX = spiderX; this.spiderX = spiderX;
this.mldsa65Verify = mldsa65Verify; this.mldsa65Verify = mldsa65Verify;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new RealityStreamSettings( return new RealityStreamSettings(
json.publicKey, json.publicKey,
json.fingerprint, json.fingerprint,
@ -680,7 +682,7 @@ export class HysteriaStreamSettings extends CommonClass {
this.disablePathMTUDiscovery = disablePathMTUDiscovery; this.disablePathMTUDiscovery = disablePathMTUDiscovery;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
let udphopPort = ''; let udphopPort = '';
let udphopIntervalMin = 30; let udphopIntervalMin = 30;
let udphopIntervalMax = 30; let udphopIntervalMax = 30;
@ -715,7 +717,7 @@ export class HysteriaStreamSettings extends CommonClass {
} }
toJson() { toJson() {
const result = { const result: any = {
version: this.version, version: this.version,
auth: this.auth, auth: this.auth,
congestion: this.congestion, congestion: this.congestion,
@ -765,7 +767,7 @@ export class SockoptStreamSettings extends CommonClass {
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
if (Object.keys(json).length === 0) return undefined; if (Object.keys(json).length === 0) return undefined;
return new SockoptStreamSettings( return new SockoptStreamSettings(
json.dialerProxy, json.dialerProxy,
@ -781,7 +783,7 @@ export class SockoptStreamSettings extends CommonClass {
} }
toJson() { toJson() {
const result = { const result: any = {
dialerProxy: this.dialerProxy, dialerProxy: this.dialerProxy,
tcpFastOpen: this.tcpFastOpen, tcpFastOpen: this.tcpFastOpen,
tcpKeepAliveInterval: this.tcpKeepAliveInterval, tcpKeepAliveInterval: this.tcpKeepAliveInterval,
@ -799,13 +801,13 @@ export class SockoptStreamSettings extends CommonClass {
} }
export class UdpMask extends CommonClass { export class UdpMask extends CommonClass {
constructor(type = 'salamander', settings = {}) { constructor(type: any = 'salamander', settings: any = {}) {
super(); super();
this.type = type; this.type = type;
this.settings = this._getDefaultSettings(type, settings); this.settings = this._getDefaultSettings(type, settings);
} }
_getDefaultSettings(type, settings = {}) { _getDefaultSettings(type: any, settings: any = {}): any {
switch (type) { switch (type) {
case 'salamander': case 'salamander':
case 'mkcp-aes128gcm': case 'mkcp-aes128gcm':
@ -846,7 +848,7 @@ export class UdpMask extends CommonClass {
} }
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new UdpMask( return new UdpMask(
json.type || 'salamander', json.type || 'salamander',
json.settings || {} json.settings || {}
@ -854,7 +856,7 @@ export class UdpMask extends CommonClass {
} }
toJson() { toJson() {
const cleanItem = item => { const cleanItem = (item: any) => {
const out = { ...item }; const out = { ...item };
if (out.type === 'array') { if (out.type === 'array') {
delete out.packet; delete out.packet;
@ -884,13 +886,13 @@ export class UdpMask extends CommonClass {
} }
export class TcpMask extends CommonClass { export class TcpMask extends CommonClass {
constructor(type = 'fragment', settings = {}) { constructor(type: any = 'fragment', settings: any = {}) {
super(); super();
this.type = type; this.type = type;
this.settings = this._getDefaultSettings(type, settings); this.settings = this._getDefaultSettings(type, settings);
} }
_getDefaultSettings(type, settings = {}) { _getDefaultSettings(type: any, settings: any = {}): any {
switch (type) { switch (type) {
case 'fragment': case 'fragment':
return { return {
@ -918,7 +920,7 @@ export class TcpMask extends CommonClass {
} }
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new TcpMask( return new TcpMask(
json.type || 'fragment', json.type || 'fragment',
json.settings || {} json.settings || {}
@ -926,7 +928,7 @@ export class TcpMask extends CommonClass {
} }
toJson() { toJson() {
const cleanItem = item => { const cleanItem = (item: any) => {
const out = { ...item }; const out = { ...item };
if (out.type === 'array') { if (out.type === 'array') {
delete out.packet; delete out.packet;
@ -939,7 +941,7 @@ export class TcpMask extends CommonClass {
let settings = this.settings; let settings = this.settings;
if (this.type === 'header-custom' && settings) { if (this.type === 'header-custom' && settings) {
const cleanGroup = group => Array.isArray(group) ? group.map(cleanItem) : group; const cleanGroup = (group: any) => Array.isArray(group) ? group.map(cleanItem) : group;
settings = { settings = {
...settings, ...settings,
clients: Array.isArray(settings.clients) ? settings.clients.map(cleanGroup) : settings.clients, clients: Array.isArray(settings.clients) ? settings.clients.map(cleanGroup) : settings.clients,
@ -956,11 +958,11 @@ export class TcpMask extends CommonClass {
export class QuicParams extends CommonClass { export class QuicParams extends CommonClass {
constructor( constructor(
congestion = 'bbr', congestion: any = 'bbr',
debug = false, debug: any = false,
brutalUp = 65537, brutalUp: any = 65537,
brutalDown = 65537, brutalDown: any = 65537,
udpHop = undefined, udpHop: any = undefined,
initStreamReceiveWindow = 8388608, initStreamReceiveWindow = 8388608,
maxStreamReceiveWindow = 8388608, maxStreamReceiveWindow = 8388608,
initConnectionReceiveWindow = 20971520, initConnectionReceiveWindow = 20971520,
@ -994,7 +996,7 @@ export class QuicParams extends CommonClass {
this.udpHop = value ? (this.udpHop || { ports: '20000-50000', interval: '5-10' }) : undefined; this.udpHop = value ? (this.udpHop || { ports: '20000-50000', interval: '5-10' }) : undefined;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
if (!json || Object.keys(json).length === 0) return undefined; if (!json || Object.keys(json).length === 0) return undefined;
return new QuicParams( return new QuicParams(
json.congestion, json.congestion,
@ -1014,7 +1016,7 @@ export class QuicParams extends CommonClass {
} }
toJson() { toJson() {
const result = { congestion: this.congestion }; const result: any = { congestion: this.congestion } as any;
if (this.debug) result.debug = this.debug; if (this.debug) result.debug = this.debug;
if (['brutal', 'force-brutal'].includes(this.congestion)) { if (['brutal', 'force-brutal'].includes(this.congestion)) {
if (this.brutalUp) result.brutalUp = this.brutalUp; if (this.brutalUp) result.brutalUp = this.brutalUp;
@ -1034,10 +1036,10 @@ export class QuicParams extends CommonClass {
} }
export class FinalMaskStreamSettings extends CommonClass { export class FinalMaskStreamSettings extends CommonClass {
constructor(tcp = [], udp = [], quicParams = undefined) { constructor(tcp: any[] = [], udp: any[] = [], quicParams: any = undefined) {
super(); super();
this.tcp = Array.isArray(tcp) ? tcp.map(t => t instanceof TcpMask ? t : new TcpMask(t.type, t.settings)) : []; this.tcp = Array.isArray(tcp) ? tcp.map((t: any) => t instanceof TcpMask ? t : new TcpMask(t.type, t.settings)) : [];
this.udp = Array.isArray(udp) ? udp.map(u => new UdpMask(u.type, u.settings)) : [new UdpMask(udp.type, udp.settings)]; this.udp = Array.isArray(udp) ? udp.map((u: any) => new UdpMask(u.type, u.settings)) : [new UdpMask((udp as any).type, (udp as any).settings)];
this.quicParams = quicParams instanceof QuicParams ? quicParams : (quicParams ? QuicParams.fromJson(quicParams) : undefined); this.quicParams = quicParams instanceof QuicParams ? quicParams : (quicParams ? QuicParams.fromJson(quicParams) : undefined);
} }
@ -1049,7 +1051,7 @@ export class FinalMaskStreamSettings extends CommonClass {
this.quicParams = value ? (this.quicParams || new QuicParams()) : undefined; this.quicParams = value ? (this.quicParams || new QuicParams()) : undefined;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new FinalMaskStreamSettings( return new FinalMaskStreamSettings(
json.tcp || [], json.tcp || [],
json.udp || [], json.udp || [],
@ -1058,12 +1060,12 @@ export class FinalMaskStreamSettings extends CommonClass {
} }
toJson() { toJson() {
const result = {}; const result: any = {} as any;
if (this.tcp && this.tcp.length > 0) { if (this.tcp && this.tcp.length > 0) {
result.tcp = this.tcp.map(t => t.toJson()); result.tcp = this.tcp.map((t: any) => t.toJson());
} }
if (this.udp && this.udp.length > 0) { if (this.udp && this.udp.length > 0) {
result.udp = this.udp.map(udp => udp.toJson()); result.udp = this.udp.map((udp: any) => udp.toJson());
} }
if (this.quicParams) { if (this.quicParams) {
result.quicParams = this.quicParams.toJson(); result.quicParams = this.quicParams.toJson();
@ -1108,7 +1110,7 @@ export class StreamSettings extends CommonClass {
this.finalmask.tcp.push(new TcpMask(type)); this.finalmask.tcp.push(new TcpMask(type));
} }
delTcpMask(index) { delTcpMask(index: number) {
if (this.finalmask.tcp) { if (this.finalmask.tcp) {
this.finalmask.tcp.splice(index, 1); this.finalmask.tcp.splice(index, 1);
} }
@ -1118,7 +1120,7 @@ export class StreamSettings extends CommonClass {
this.finalmask.udp.push(new UdpMask(type)); this.finalmask.udp.push(new UdpMask(type));
} }
delUdpMask(index) { delUdpMask(index: number) {
if (this.finalmask.udp) { if (this.finalmask.udp) {
this.finalmask.udp.splice(index, 1); this.finalmask.udp.splice(index, 1);
} }
@ -1147,7 +1149,7 @@ export class StreamSettings extends CommonClass {
this.sockopt = value ? new SockoptStreamSettings() : undefined; this.sockopt = value ? new SockoptStreamSettings() : undefined;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
// Xray-core supports both "xhttpSettings" and "splithttpSettings" (backward-compat alias) // Xray-core supports both "xhttpSettings" and "splithttpSettings" (backward-compat alias)
const xhttpJson = json.xhttpSettings ?? json.splithttpSettings; const xhttpJson = json.xhttpSettings ?? json.splithttpSettings;
// Normalize "splithttp" network name to "xhttp" for internal consistency // Normalize "splithttp" network name to "xhttp" for internal consistency
@ -1198,7 +1200,7 @@ export class Mux extends CommonClass {
this.xudpProxyUDP443 = xudpProxyUDP443; this.xudpProxyUDP443 = xudpProxyUDP443;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
if (Object.keys(json).length === 0) return undefined; if (Object.keys(json).length === 0) return undefined;
return new Mux( return new Mux(
json.enabled, json.enabled,
@ -1219,13 +1221,28 @@ export class Mux extends CommonClass {
} }
export class Outbound extends CommonClass { export class Outbound extends CommonClass {
static Settings: any;
static FreedomSettings: any;
static BlackholeSettings: any;
static LoopbackSettings: any;
static DNSRule: any;
static DNSSettings: any;
static VmessSettings: any;
static VLESSSettings: any;
static TrojanSettings: any;
static ShadowsocksSettings: any;
static SocksSettings: any;
static HttpSettings: any;
static WireguardSettings: any;
static HysteriaSettings: any;
constructor( constructor(
tag = '', tag: any = '',
protocol = Protocols.VLESS, protocol: any = Protocols.VLESS,
settings = null, settings: any = null,
streamSettings = new StreamSettings(), streamSettings: any = new StreamSettings(),
sendThrough, sendThrough?: any,
mux = new Mux(), mux: any = new Mux(),
) { ) {
super(); super();
this.tag = tag; this.tag = tag;
@ -1320,7 +1337,7 @@ export class Outbound extends CommonClass {
return [Protocols.Socks, Protocols.HTTP].includes(this.protocol); return [Protocols.Socks, Protocols.HTTP].includes(this.protocol);
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new Outbound( return new Outbound(
json.tag, json.tag,
json.protocol, json.protocol,
@ -1351,7 +1368,7 @@ export class Outbound extends CommonClass {
}; };
} }
static fromLink(link) { static fromLink(link: any) {
const data = link.split('://'); const data = link.split('://');
if (data.length != 2) return null; if (data.length != 2) return null;
switch (data[0].toLowerCase()) { switch (data[0].toLowerCase()) {
@ -1369,7 +1386,7 @@ export class Outbound extends CommonClass {
} }
} }
static fromVmessLink(json = {}) { static fromVmessLink(json: any = {}) {
let stream = new StreamSettings(json.net, json.tls); let stream = new StreamSettings(json.net, json.tls);
let network = json.net; let network = json.net;
@ -1402,7 +1419,7 @@ export class Outbound extends CommonClass {
if (typeof json.xPaddingBytes === 'string' && json.xPaddingBytes) xh.xPaddingBytes = json.xPaddingBytes; if (typeof json.xPaddingBytes === 'string' && json.xPaddingBytes) xh.xPaddingBytes = json.xPaddingBytes;
if (json.xPaddingObfsMode === true) { if (json.xPaddingObfsMode === true) {
xh.xPaddingObfsMode = true; xh.xPaddingObfsMode = true;
["xPaddingKey", "xPaddingHeader", "xPaddingPlacement", "xPaddingMethod"].forEach(k => { ["xPaddingKey", "xPaddingHeader", "xPaddingPlacement", "xPaddingMethod"].forEach((k: string) => {
if (typeof json[k] === 'string' && json[k]) xh[k] = json[k]; if (typeof json[k] === 'string' && json[k]) xh[k] = json[k];
}); });
} }
@ -1414,7 +1431,7 @@ export class Outbound extends CommonClass {
"uplinkDataPlacement", "uplinkDataKey", "uplinkDataPlacement", "uplinkDataKey",
"scMaxEachPostBytes", "scMinPostsIntervalMs", "scMaxEachPostBytes", "scMinPostsIntervalMs",
]; ];
xFields.forEach(k => { xFields.forEach((k: string) => {
if (typeof json[k] === 'string' && json[k]) xh[k] = json[k]; if (typeof json[k] === 'string' && json[k]) xh[k] = json[k];
}); });
if (typeof json.uplinkChunkSize === 'number' && json.uplinkChunkSize !== 0) xh.uplinkChunkSize = json.uplinkChunkSize; if (typeof json.uplinkChunkSize === 'number' && json.uplinkChunkSize !== 0) xh.uplinkChunkSize = json.uplinkChunkSize;
@ -1451,7 +1468,7 @@ export class Outbound extends CommonClass {
return new Outbound(json.ps, Protocols.VMess, new Outbound.VmessSettings(json.add, port, json.id, json.scy), stream); return new Outbound(json.ps, Protocols.VMess, new Outbound.VmessSettings(json.add, port, json.id, json.scy), stream);
} }
static fromParamLink(link) { static fromParamLink(link: any) {
const url = new URL(link); const url = new URL(link);
let type = url.searchParams.get('type') ?? 'tcp'; let type = url.searchParams.get('type') ?? 'tcp';
let security = url.searchParams.get('security') ?? 'none'; let security = url.searchParams.get('security') ?? 'none';
@ -1496,7 +1513,7 @@ export class Outbound extends CommonClass {
const extra = JSON.parse(extraRaw); const extra = JSON.parse(extraRaw);
if (typeof extra.xPaddingBytes === 'string' && extra.xPaddingBytes) xh.xPaddingBytes = extra.xPaddingBytes; if (typeof extra.xPaddingBytes === 'string' && extra.xPaddingBytes) xh.xPaddingBytes = extra.xPaddingBytes;
if (extra.xPaddingObfsMode === true) xh.xPaddingObfsMode = true; if (extra.xPaddingObfsMode === true) xh.xPaddingObfsMode = true;
["xPaddingKey", "xPaddingHeader", "xPaddingPlacement", "xPaddingMethod"].forEach(k => { ["xPaddingKey", "xPaddingHeader", "xPaddingPlacement", "xPaddingMethod"].forEach((k: string) => {
if (typeof extra[k] === 'string' && extra[k]) xh[k] = extra[k]; if (typeof extra[k] === 'string' && extra[k]) xh[k] = extra[k];
}); });
if (!xh.mode && typeof extra.mode === 'string' && extra.mode) xh.mode = extra.mode; if (!xh.mode && typeof extra.mode === 'string' && extra.mode) xh.mode = extra.mode;
@ -1508,7 +1525,7 @@ export class Outbound extends CommonClass {
"uplinkDataPlacement", "uplinkDataKey", "uplinkDataPlacement", "uplinkDataKey",
"scMaxEachPostBytes", "scMinPostsIntervalMs", "scMaxEachPostBytes", "scMinPostsIntervalMs",
]; ];
xFields.forEach(k => { xFields.forEach((k: string) => {
if (typeof extra[k] === 'string' && extra[k]) xh[k] = extra[k]; if (typeof extra[k] === 'string' && extra[k]) xh[k] = extra[k];
}); });
if (typeof extra.uplinkChunkSize === 'number' && extra.uplinkChunkSize !== 0) xh.uplinkChunkSize = extra.uplinkChunkSize; if (typeof extra.uplinkChunkSize === 'number' && extra.uplinkChunkSize !== 0) xh.uplinkChunkSize = extra.uplinkChunkSize;
@ -1564,10 +1581,11 @@ export class Outbound extends CommonClass {
case Protocols.Trojan: case Protocols.Trojan:
settings = new Outbound.TrojanSettings(address, port, userData); settings = new Outbound.TrojanSettings(address, port, userData);
break; break;
case Protocols.Shadowsocks: case Protocols.Shadowsocks: {
let method = userData.splice(0, 1)[0]; const method = userData.splice(0, 1)[0];
settings = new Outbound.ShadowsocksSettings(address, port, userData.join(":"), method, true); settings = new Outbound.ShadowsocksSettings(address, port, userData.join(":"), method, true);
break; break;
}
default: default:
return null; return null;
} }
@ -1585,7 +1603,7 @@ export class Outbound extends CommonClass {
return new Outbound(remark, protocol, settings, stream); return new Outbound(remark, protocol, settings, stream);
} }
static fromHysteriaLink(link) { static fromHysteriaLink(link: any) {
// Parse hysteria2://password@address:port[?param1=value1&param2=value2...][#remarks] // Parse hysteria2://password@address:port[?param1=value1&param2=value2...][#remarks]
const regex = /^hysteria2?:\/\/([^@]+)@([^:?#]+):(\d+)([^#]*)(#.*)?$/; const regex = /^hysteria2?:\/\/([^@]+)@([^:?#]+):(\d+)([^#]*)(#.*)?$/;
const match = link.match(regex); const match = link.match(regex);
@ -1619,7 +1637,7 @@ export class Outbound extends CommonClass {
stream.hysteria.udphopPort = urlParams.get('udphopPort') ?? ''; stream.hysteria.udphopPort = urlParams.get('udphopPort') ?? '';
// Support both old single interval and new min/max range // Support both old single interval and new min/max range
if (urlParams.has('udphopInterval')) { if (urlParams.has('udphopInterval')) {
const interval = parseInt(urlParams.get('udphopInterval')); const interval = parseInt(urlParams.get('udphopInterval')!);
stream.hysteria.udphopIntervalMin = interval; stream.hysteria.udphopIntervalMin = interval;
stream.hysteria.udphopIntervalMax = interval; stream.hysteria.udphopIntervalMax = interval;
} else { } else {
@ -1629,22 +1647,22 @@ export class Outbound extends CommonClass {
// Optional QUIC parameters for FinalMask support and hysteria2 share links // Optional QUIC parameters for FinalMask support and hysteria2 share links
if (urlParams.has('initStreamReceiveWindow')) { if (urlParams.has('initStreamReceiveWindow')) {
stream.hysteria.initStreamReceiveWindow = parseInt(urlParams.get('initStreamReceiveWindow')); stream.hysteria.initStreamReceiveWindow = parseInt(urlParams.get('initStreamReceiveWindow')!);
} }
if (urlParams.has('maxStreamReceiveWindow')) { if (urlParams.has('maxStreamReceiveWindow')) {
stream.hysteria.maxStreamReceiveWindow = parseInt(urlParams.get('maxStreamReceiveWindow')); stream.hysteria.maxStreamReceiveWindow = parseInt(urlParams.get('maxStreamReceiveWindow')!);
} }
if (urlParams.has('initConnectionReceiveWindow')) { if (urlParams.has('initConnectionReceiveWindow')) {
stream.hysteria.initConnectionReceiveWindow = parseInt(urlParams.get('initConnectionReceiveWindow')); stream.hysteria.initConnectionReceiveWindow = parseInt(urlParams.get('initConnectionReceiveWindow')!);
} }
if (urlParams.has('maxConnectionReceiveWindow')) { if (urlParams.has('maxConnectionReceiveWindow')) {
stream.hysteria.maxConnectionReceiveWindow = parseInt(urlParams.get('maxConnectionReceiveWindow')); stream.hysteria.maxConnectionReceiveWindow = parseInt(urlParams.get('maxConnectionReceiveWindow')!);
} }
if (urlParams.has('maxIdleTimeout')) { if (urlParams.has('maxIdleTimeout')) {
stream.hysteria.maxIdleTimeout = parseInt(urlParams.get('maxIdleTimeout')); stream.hysteria.maxIdleTimeout = parseInt(urlParams.get('maxIdleTimeout')!);
} }
if (urlParams.has('keepAlivePeriod')) { if (urlParams.has('keepAlivePeriod')) {
stream.hysteria.keepAlivePeriod = parseInt(urlParams.get('keepAlivePeriod')); stream.hysteria.keepAlivePeriod = parseInt(urlParams.get('keepAlivePeriod')!);
} }
if (urlParams.has('disablePathMTUDiscovery')) { if (urlParams.has('disablePathMTUDiscovery')) {
stream.hysteria.disablePathMTUDiscovery = urlParams.get('disablePathMTUDiscovery') === 'true'; stream.hysteria.disablePathMTUDiscovery = urlParams.get('disablePathMTUDiscovery') === 'true';
@ -1693,12 +1711,12 @@ export class Outbound extends CommonClass {
} }
Outbound.Settings = class extends CommonClass { Outbound.Settings = class extends CommonClass {
constructor(protocol) { constructor(protocol: any) {
super(); super();
this.protocol = protocol; this.protocol = protocol;
} }
static getSettings(protocol) { static getSettings(protocol: any): any {
switch (protocol) { switch (protocol) {
case Protocols.Freedom: return new Outbound.FreedomSettings(); case Protocols.Freedom: return new Outbound.FreedomSettings();
case Protocols.Blackhole: return new Outbound.BlackholeSettings(); case Protocols.Blackhole: return new Outbound.BlackholeSettings();
@ -1716,7 +1734,7 @@ Outbound.Settings = class extends CommonClass {
} }
} }
static fromJson(protocol, json) { static fromJson(protocol: any, json: any): any {
switch (protocol) { switch (protocol) {
case Protocols.Freedom: return Outbound.FreedomSettings.fromJson(json); case Protocols.Freedom: return Outbound.FreedomSettings.fromJson(json);
case Protocols.Blackhole: return Outbound.BlackholeSettings.fromJson(json); case Protocols.Blackhole: return Outbound.BlackholeSettings.fromJson(json);
@ -1752,7 +1770,7 @@ Outbound.FreedomSettings = class extends CommonClass {
this.fragment = fragment || {}; this.fragment = fragment || {};
this.noises = Array.isArray(noises) ? noises : []; this.noises = Array.isArray(noises) ? noises : [];
this.finalRules = Array.isArray(finalRules) this.finalRules = Array.isArray(finalRules)
? finalRules.map(rule => rule instanceof Outbound.FreedomSettings.FinalRule ? rule : Outbound.FreedomSettings.FinalRule.fromJson(rule)) ? finalRules.map((rule: any) => rule instanceof Outbound.FreedomSettings.FinalRule ? rule : Outbound.FreedomSettings.FinalRule.fromJson(rule))
: []; : [];
} }
@ -1760,7 +1778,7 @@ Outbound.FreedomSettings = class extends CommonClass {
this.noises.push(new Outbound.FreedomSettings.Noise()); this.noises.push(new Outbound.FreedomSettings.Noise());
} }
delNoise(index) { delNoise(index: number) {
this.noises.splice(index, 1); this.noises.splice(index, 1);
} }
@ -1768,13 +1786,13 @@ Outbound.FreedomSettings = class extends CommonClass {
this.finalRules.push(new Outbound.FreedomSettings.FinalRule(action)); this.finalRules.push(new Outbound.FreedomSettings.FinalRule(action));
} }
delFinalRule(index) { delFinalRule(index: number) {
this.finalRules.splice(index, 1); this.finalRules.splice(index, 1);
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
const finalRules = Array.isArray(json.finalRules) const finalRules = Array.isArray(json.finalRules)
? json.finalRules.map(rule => Outbound.FreedomSettings.FinalRule.fromJson(rule)) ? json.finalRules.map((rule: any) => Outbound.FreedomSettings.FinalRule.fromJson(rule))
: []; : [];
// Backward compatibility: map legacy ipsBlocked entries to blocking finalRules. // Backward compatibility: map legacy ipsBlocked entries to blocking finalRules.
@ -1786,7 +1804,7 @@ Outbound.FreedomSettings = class extends CommonClass {
json.domainStrategy, json.domainStrategy,
json.redirect, json.redirect,
json.fragment ? Outbound.FreedomSettings.Fragment.fromJson(json.fragment) : {}, json.fragment ? Outbound.FreedomSettings.Fragment.fromJson(json.fragment) : {},
json.noises ? json.noises.map(noise => Outbound.FreedomSettings.Noise.fromJson(noise)) : [], json.noises ? json.noises.map((noise: any) => Outbound.FreedomSettings.Noise.fromJson(noise)) : [],
finalRules, finalRules,
); );
} }
@ -1816,7 +1834,7 @@ Outbound.FreedomSettings.Fragment = class extends CommonClass {
this.maxSplit = maxSplit; this.maxSplit = maxSplit;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new Outbound.FreedomSettings.Fragment( return new Outbound.FreedomSettings.Fragment(
json.packets, json.packets,
json.length, json.length,
@ -1840,7 +1858,7 @@ Outbound.FreedomSettings.Noise = class extends CommonClass {
this.applyTo = applyTo; this.applyTo = applyTo;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new Outbound.FreedomSettings.Noise( return new Outbound.FreedomSettings.Noise(
json.type, json.type,
json.packet, json.packet,
@ -1869,7 +1887,7 @@ Outbound.FreedomSettings.FinalRule = class extends CommonClass {
this.blockDelay = blockDelay; this.blockDelay = blockDelay;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new Outbound.FreedomSettings.FinalRule( return new Outbound.FreedomSettings.FinalRule(
json.action, json.action,
Array.isArray(json.network) ? json.network.join(',') : json.network, Array.isArray(json.network) ? json.network.join(',') : json.network,
@ -1891,12 +1909,12 @@ Outbound.FreedomSettings.FinalRule = class extends CommonClass {
}; };
Outbound.BlackholeSettings = class extends CommonClass { Outbound.BlackholeSettings = class extends CommonClass {
constructor(type) { constructor(type?: any) {
super(); super();
this.type = type; this.type = type;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new Outbound.BlackholeSettings( return new Outbound.BlackholeSettings(
json.response ? json.response.type : undefined, json.response ? json.response.type : undefined,
); );
@ -1915,7 +1933,7 @@ Outbound.LoopbackSettings = class extends CommonClass {
this.inboundTag = inboundTag; this.inboundTag = inboundTag;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new Outbound.LoopbackSettings(json.inboundTag || ''); return new Outbound.LoopbackSettings(json.inboundTag || '');
} }
@ -1934,7 +1952,7 @@ Outbound.DNSRule = class extends CommonClass {
this.domain = domain; this.domain = domain;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new Outbound.DNSRule( return new Outbound.DNSRule(
json.action, json.action,
normalizeDNSRuleField(json.qtype), normalizeDNSRuleField(json.qtype),
@ -1943,7 +1961,7 @@ Outbound.DNSRule = class extends CommonClass {
} }
toJson() { toJson() {
const rule = { const rule: any = {
action: normalizeDNSRuleAction(this.action), action: normalizeDNSRuleAction(this.action),
}; };
@ -1981,18 +1999,18 @@ Outbound.DNSSettings = class extends CommonClass {
this.rewriteAddress = rewriteAddress; this.rewriteAddress = rewriteAddress;
this.rewritePort = rewritePort; this.rewritePort = rewritePort;
this.userLevel = userLevel; this.userLevel = userLevel;
this.rules = Array.isArray(rules) ? rules.map(rule => rule instanceof Outbound.DNSRule ? rule : Outbound.DNSRule.fromJson(rule)) : []; this.rules = Array.isArray(rules) ? rules.map((rule: any) => rule instanceof Outbound.DNSRule ? rule : Outbound.DNSRule.fromJson(rule)) : [];
} }
addRule(action = 'direct') { addRule(action = 'direct') {
this.rules.push(new Outbound.DNSRule(action)); this.rules.push(new Outbound.DNSRule(action));
} }
delRule(index) { delRule(index: number) {
this.rules.splice(index, 1); this.rules.splice(index, 1);
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
// Spec uses rewrite{Network,Address,Port}; older configs used the // Spec uses rewrite{Network,Address,Port}; older configs used the
// bare network/address/port keys — accept both so existing saved // bare network/address/port keys — accept both so existing saved
// configs keep working after the migration. // configs keep working after the migration.
@ -2006,7 +2024,7 @@ Outbound.DNSSettings = class extends CommonClass {
} }
toJson() { toJson() {
const json = {}; const json: any = {};
if (!ObjectUtil.isEmpty(this.rewriteNetwork)) json.rewriteNetwork = this.rewriteNetwork; if (!ObjectUtil.isEmpty(this.rewriteNetwork)) json.rewriteNetwork = this.rewriteNetwork;
if (!ObjectUtil.isEmpty(this.rewriteAddress)) json.rewriteAddress = this.rewriteAddress; if (!ObjectUtil.isEmpty(this.rewriteAddress)) json.rewriteAddress = this.rewriteAddress;
if (this.rewritePort > 0) json.rewritePort = this.rewritePort; if (this.rewritePort > 0) json.rewritePort = this.rewritePort;
@ -2016,7 +2034,7 @@ Outbound.DNSSettings = class extends CommonClass {
} }
}; };
Outbound.VmessSettings = class extends CommonClass { Outbound.VmessSettings = class extends CommonClass {
constructor(address, port, id, security) { constructor(address?: any, port?: any, id?: any, security?: any) {
super(); super();
this.address = address; this.address = address;
this.port = port; this.port = port;
@ -2024,7 +2042,7 @@ Outbound.VmessSettings = class extends CommonClass {
this.security = security; this.security = security;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
if (!ObjectUtil.isArrEmpty(json.vnext)) { if (!ObjectUtil.isArrEmpty(json.vnext)) {
const v = json.vnext[0] || {}; const v = json.vnext[0] || {};
const u = ObjectUtil.isArrEmpty(v.users) ? {} : v.users[0]; const u = ObjectUtil.isArrEmpty(v.users) ? {} : v.users[0];
@ -2051,7 +2069,7 @@ Outbound.VmessSettings = class extends CommonClass {
} }
}; };
Outbound.VLESSSettings = class extends CommonClass { Outbound.VLESSSettings = class extends CommonClass {
constructor(address, port, id, flow, encryption = 'none', reverseTag = '', reverseSniffing = new ReverseSniffing(), testpre = 0, testseed = []) { constructor(address?: any, port?: any, id?: any, flow?: any, encryption: any = 'none', reverseTag: any = '', reverseSniffing: any = new ReverseSniffing(), testpre: any = 0, testseed: any[] = []) {
super(); super();
this.address = address; this.address = address;
this.port = port; this.port = port;
@ -2064,7 +2082,7 @@ Outbound.VLESSSettings = class extends CommonClass {
this.testseed = testseed; this.testseed = testseed;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
// Handle v2rayN-style nested vnext array (standard Xray JSON format) // Handle v2rayN-style nested vnext array (standard Xray JSON format)
if (!ObjectUtil.isArrEmpty(json.vnext)) { if (!ObjectUtil.isArrEmpty(json.vnext)) {
const v = json.vnext[0] || {}; const v = json.vnext[0] || {};
@ -2072,7 +2090,7 @@ Outbound.VLESSSettings = class extends CommonClass {
const saved = json.testseed; const saved = json.testseed;
const testseed = (Array.isArray(saved) const testseed = (Array.isArray(saved)
&& saved.length === 4 && saved.length === 4
&& saved.every(v => Number.isInteger(v) && v > 0)) && saved.every((v: any) => Number.isInteger(v) && v > 0))
? saved ? saved
: []; : [];
return new Outbound.VLESSSettings( return new Outbound.VLESSSettings(
@ -2091,7 +2109,7 @@ Outbound.VLESSSettings = class extends CommonClass {
const saved = json.testseed; const saved = json.testseed;
const testseed = (Array.isArray(saved) const testseed = (Array.isArray(saved)
&& saved.length === 4 && saved.length === 4
&& saved.every(v => Number.isInteger(v) && v > 0)) && saved.every((v: any) => Number.isInteger(v) && v > 0))
? saved ? saved
: []; : [];
return new Outbound.VLESSSettings( return new Outbound.VLESSSettings(
@ -2108,7 +2126,7 @@ Outbound.VLESSSettings = class extends CommonClass {
} }
toJson() { toJson() {
const result = { const result: any = {
address: this.address, address: this.address,
port: this.port, port: this.port,
id: this.id, id: this.id,
@ -2130,7 +2148,7 @@ Outbound.VLESSSettings = class extends CommonClass {
} }
if (Array.isArray(this.testseed) if (Array.isArray(this.testseed)
&& this.testseed.length === 4 && this.testseed.length === 4
&& this.testseed.every(v => Number.isInteger(v) && v > 0)) { && this.testseed.every((v: any) => Number.isInteger(v) && v > 0)) {
result.testseed = this.testseed; result.testseed = this.testseed;
} }
} }
@ -2138,14 +2156,14 @@ Outbound.VLESSSettings = class extends CommonClass {
} }
}; };
Outbound.TrojanSettings = class extends CommonClass { Outbound.TrojanSettings = class extends CommonClass {
constructor(address, port, password) { constructor(address?: any, port?: any, password?: any) {
super(); super();
this.address = address; this.address = address;
this.port = port; this.port = port;
this.password = password; this.password = password;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
if (ObjectUtil.isArrEmpty(json.servers)) return new Outbound.TrojanSettings(); if (ObjectUtil.isArrEmpty(json.servers)) return new Outbound.TrojanSettings();
return new Outbound.TrojanSettings( return new Outbound.TrojanSettings(
json.servers[0].address, json.servers[0].address,
@ -2165,7 +2183,7 @@ Outbound.TrojanSettings = class extends CommonClass {
} }
}; };
Outbound.ShadowsocksSettings = class extends CommonClass { Outbound.ShadowsocksSettings = class extends CommonClass {
constructor(address, port, password, method, uot, UoTVersion) { constructor(address?: any, port?: any, password?: any, method?: any, uot?: any, UoTVersion?: any) {
super(); super();
this.address = address; this.address = address;
this.port = port; this.port = port;
@ -2175,7 +2193,7 @@ Outbound.ShadowsocksSettings = class extends CommonClass {
this.UoTVersion = UoTVersion; this.UoTVersion = UoTVersion;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
let servers = json.servers; let servers = json.servers;
if (ObjectUtil.isArrEmpty(servers)) servers = [{}]; if (ObjectUtil.isArrEmpty(servers)) servers = [{}];
return new Outbound.ShadowsocksSettings( return new Outbound.ShadowsocksSettings(
@ -2203,7 +2221,7 @@ Outbound.ShadowsocksSettings = class extends CommonClass {
}; };
Outbound.SocksSettings = class extends CommonClass { Outbound.SocksSettings = class extends CommonClass {
constructor(address, port, user, pass) { constructor(address?: any, port?: any, user?: any, pass?: any) {
super(); super();
this.address = address; this.address = address;
this.port = port; this.port = port;
@ -2211,7 +2229,7 @@ Outbound.SocksSettings = class extends CommonClass {
this.pass = pass; this.pass = pass;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
let servers = json.servers; let servers = json.servers;
if (ObjectUtil.isArrEmpty(servers)) servers = [{ users: [{}] }]; if (ObjectUtil.isArrEmpty(servers)) servers = [{ users: [{}] }];
return new Outbound.SocksSettings( return new Outbound.SocksSettings(
@ -2233,7 +2251,7 @@ Outbound.SocksSettings = class extends CommonClass {
} }
}; };
Outbound.HttpSettings = class extends CommonClass { Outbound.HttpSettings = class extends CommonClass {
constructor(address, port, user, pass) { constructor(address?: any, port?: any, user?: any, pass?: any) {
super(); super();
this.address = address; this.address = address;
this.port = port; this.port = port;
@ -2241,7 +2259,7 @@ Outbound.HttpSettings = class extends CommonClass {
this.pass = pass; this.pass = pass;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
let servers = json.servers; let servers = json.servers;
if (ObjectUtil.isArrEmpty(servers)) servers = [{ users: [{}] }]; if (ObjectUtil.isArrEmpty(servers)) servers = [{ users: [{}] }];
return new Outbound.HttpSettings( return new Outbound.HttpSettings(
@ -2290,11 +2308,11 @@ Outbound.WireguardSettings = class extends CommonClass {
this.peers.push(new Outbound.WireguardSettings.Peer()); this.peers.push(new Outbound.WireguardSettings.Peer());
} }
delPeer(index) { delPeer(index: number) {
this.peers.splice(index, 1); this.peers.splice(index, 1);
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new Outbound.WireguardSettings( return new Outbound.WireguardSettings(
json.mtu, json.mtu,
json.secretKey, json.secretKey,
@ -2302,7 +2320,7 @@ Outbound.WireguardSettings = class extends CommonClass {
json.workers, json.workers,
json.domainStrategy, json.domainStrategy,
json.reserved, json.reserved,
json.peers.map(peer => Outbound.WireguardSettings.Peer.fromJson(peer)), json.peers.map((peer: any) => Outbound.WireguardSettings.Peer.fromJson(peer)),
json.noKernelTun, json.noKernelTun,
); );
} }
@ -2337,7 +2355,7 @@ Outbound.WireguardSettings.Peer = class extends CommonClass {
this.keepAlive = keepAlive; this.keepAlive = keepAlive;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
return new Outbound.WireguardSettings.Peer( return new Outbound.WireguardSettings.Peer(
json.publicKey, json.publicKey,
json.preSharedKey, json.preSharedKey,
@ -2366,7 +2384,7 @@ Outbound.HysteriaSettings = class extends CommonClass {
this.version = version; this.version = version;
} }
static fromJson(json = {}) { static fromJson(json: any = {}): any {
if (Object.keys(json).length === 0) return new Outbound.HysteriaSettings(); if (Object.keys(json).length === 0) return new Outbound.HysteriaSettings();
return new Outbound.HysteriaSettings( return new Outbound.HysteriaSettings(
json.address, json.address,