231 lines
6.2 KiB
TypeScript
231 lines
6.2 KiB
TypeScript
import { z } from "zod";
|
|
import {
|
|
CERT_MODES,
|
|
ENCRYPTION_MODES,
|
|
ENCRYPTION_RTT,
|
|
ENCRYPTION_TYPES,
|
|
FLOWS,
|
|
multiplexLevels,
|
|
SECURITY,
|
|
SS_CIPHERS,
|
|
TRANSPORTS,
|
|
TUIC_CONGESTION,
|
|
TUIC_UDP_RELAY_MODES,
|
|
XHTTP_MODES,
|
|
} from "./constants";
|
|
|
|
const nullableString = z.string().nullish();
|
|
const nullableBool = z.boolean().nullish();
|
|
const nullablePort = z.number().int().min(0).max(65_535).nullish();
|
|
const nullableRatio = z.number().min(0).nullish();
|
|
|
|
const ss = z.object({
|
|
ratio: nullableRatio,
|
|
type: z.literal("shadowsocks"),
|
|
enable: nullableBool,
|
|
port: nullablePort,
|
|
cipher: z.enum(SS_CIPHERS).nullish(),
|
|
server_key: nullableString,
|
|
obfs: z.enum(["none", "http", "tls"] as const).nullish(),
|
|
obfs_host: nullableString,
|
|
obfs_path: nullableString,
|
|
cert_mode: z.enum(CERT_MODES).nullish(),
|
|
cert_dns_provider: nullableString,
|
|
cert_dns_env: nullableString,
|
|
});
|
|
|
|
const vmess = z.object({
|
|
ratio: nullableRatio,
|
|
type: z.literal("vmess"),
|
|
enable: nullableBool,
|
|
host: nullableString,
|
|
port: nullablePort,
|
|
transport: z.enum(TRANSPORTS.vmess).nullish(),
|
|
security: z.enum(SECURITY.vmess).nullish(),
|
|
path: nullableString,
|
|
service_name: nullableString,
|
|
sni: nullableString,
|
|
allow_insecure: nullableBool,
|
|
fingerprint: nullableString,
|
|
cert_mode: z.enum(CERT_MODES).nullish(),
|
|
cert_dns_provider: nullableString,
|
|
cert_dns_env: nullableString,
|
|
});
|
|
|
|
const vless = z.object({
|
|
ratio: nullableRatio,
|
|
type: z.literal("vless"),
|
|
enable: nullableBool,
|
|
host: nullableString,
|
|
port: nullablePort,
|
|
transport: z.enum(TRANSPORTS.vless).nullish(),
|
|
security: z.enum(SECURITY.vless).nullish(),
|
|
path: nullableString,
|
|
service_name: nullableString,
|
|
flow: z.enum(FLOWS.vless).nullish(),
|
|
sni: nullableString,
|
|
allow_insecure: nullableBool,
|
|
fingerprint: nullableString,
|
|
reality_server_addr: nullableString,
|
|
reality_server_port: nullablePort,
|
|
reality_private_key: nullableString,
|
|
reality_public_key: nullableString,
|
|
reality_short_id: nullableString,
|
|
xhttp_mode: z.enum(XHTTP_MODES).nullish(),
|
|
xhttp_extra: nullableString,
|
|
encryption: z.enum(ENCRYPTION_TYPES).nullish(),
|
|
encryption_mode: z.enum(ENCRYPTION_MODES).nullish(),
|
|
encryption_rtt: z.enum(ENCRYPTION_RTT).nullish(),
|
|
encryption_ticket: nullableString,
|
|
encryption_server_padding: nullableString,
|
|
encryption_private_key: nullableString,
|
|
encryption_client_padding: nullableString,
|
|
encryption_password: nullableString,
|
|
cert_mode: z.enum(CERT_MODES).nullish(),
|
|
cert_dns_provider: nullableString,
|
|
cert_dns_env: nullableString,
|
|
});
|
|
|
|
const trojan = z.object({
|
|
ratio: nullableRatio,
|
|
type: z.literal("trojan"),
|
|
enable: nullableBool,
|
|
host: nullableString,
|
|
port: nullablePort,
|
|
transport: z.enum(TRANSPORTS.trojan).nullish(),
|
|
security: z.enum(SECURITY.trojan).nullish(),
|
|
path: nullableString,
|
|
service_name: nullableString,
|
|
sni: nullableString,
|
|
allow_insecure: nullableBool,
|
|
fingerprint: nullableString,
|
|
cert_mode: z.enum(CERT_MODES).nullish(),
|
|
cert_dns_provider: nullableString,
|
|
cert_dns_env: nullableString,
|
|
});
|
|
|
|
const hysteria = z.object({
|
|
ratio: nullableRatio,
|
|
type: z.literal("hysteria"),
|
|
enable: nullableBool,
|
|
hop_ports: nullableString,
|
|
hop_interval: z.number().nullish(),
|
|
obfs_password: nullableString,
|
|
obfs: z.enum(["none", "salamander"] as const).nullish(),
|
|
port: nullablePort,
|
|
security: z.enum(SECURITY.hysteria).nullish(),
|
|
sni: nullableString,
|
|
allow_insecure: nullableBool,
|
|
fingerprint: nullableString,
|
|
up_mbps: z.number().nullish(),
|
|
down_mbps: z.number().nullish(),
|
|
cert_mode: z.enum(CERT_MODES).nullish(),
|
|
cert_dns_provider: nullableString,
|
|
cert_dns_env: nullableString,
|
|
});
|
|
|
|
const tuic = z.object({
|
|
ratio: nullableRatio,
|
|
type: z.literal("tuic"),
|
|
enable: nullableBool,
|
|
host: nullableString,
|
|
port: nullablePort,
|
|
disable_sni: z.boolean().nullish(),
|
|
reduce_rtt: z.boolean().nullish(),
|
|
udp_relay_mode: z.enum(TUIC_UDP_RELAY_MODES).nullish(),
|
|
congestion_controller: z.enum(TUIC_CONGESTION).nullish(),
|
|
security: z.enum(SECURITY.tuic).nullish(),
|
|
sni: nullableString,
|
|
allow_insecure: nullableBool,
|
|
fingerprint: nullableString,
|
|
cert_mode: z.enum(CERT_MODES).nullish(),
|
|
cert_dns_provider: nullableString,
|
|
cert_dns_env: nullableString,
|
|
});
|
|
|
|
const anytls = z.object({
|
|
ratio: nullableRatio,
|
|
type: z.literal("anytls"),
|
|
enable: nullableBool,
|
|
port: nullablePort,
|
|
security: z.enum(SECURITY.anytls).nullish(),
|
|
sni: nullableString,
|
|
allow_insecure: nullableBool,
|
|
fingerprint: nullableString,
|
|
padding_scheme: nullableString,
|
|
cert_mode: z.enum(CERT_MODES).nullish(),
|
|
cert_dns_provider: nullableString,
|
|
cert_dns_env: nullableString,
|
|
reality_server_addr: nullableString,
|
|
reality_server_port: nullablePort,
|
|
reality_private_key: nullableString,
|
|
reality_public_key: nullableString,
|
|
reality_short_id: nullableString,
|
|
});
|
|
|
|
const socks = z.object({
|
|
ratio: nullableRatio,
|
|
type: z.literal("socks"),
|
|
enable: nullableBool,
|
|
port: nullablePort,
|
|
});
|
|
|
|
const naive = z.object({
|
|
ratio: nullableRatio,
|
|
type: z.literal("naive"),
|
|
enable: nullableBool,
|
|
port: nullablePort,
|
|
security: z.enum(SECURITY.naive).nullish(),
|
|
sni: nullableString,
|
|
allow_insecure: nullableBool,
|
|
fingerprint: nullableString,
|
|
cert_mode: z.enum(CERT_MODES).nullish(),
|
|
cert_dns_provider: nullableString,
|
|
cert_dns_env: nullableString,
|
|
});
|
|
|
|
const http = z.object({
|
|
ratio: nullableRatio,
|
|
type: z.literal("http"),
|
|
enable: nullableBool,
|
|
port: nullablePort,
|
|
security: z.enum(SECURITY.http).nullish(),
|
|
sni: nullableString,
|
|
allow_insecure: nullableBool,
|
|
fingerprint: nullableString,
|
|
cert_mode: z.enum(CERT_MODES).nullish(),
|
|
cert_dns_provider: nullableString,
|
|
cert_dns_env: nullableString,
|
|
});
|
|
|
|
const mieru = z.object({
|
|
ratio: nullableRatio,
|
|
type: z.literal("mieru"),
|
|
enable: nullableBool,
|
|
port: nullablePort,
|
|
multiplex: z.enum(multiplexLevels).nullish(),
|
|
transport: z.enum(TRANSPORTS.mieru).nullish(),
|
|
});
|
|
|
|
export const protocolApiScheme = z.discriminatedUnion("type", [
|
|
ss,
|
|
vmess,
|
|
vless,
|
|
trojan,
|
|
hysteria,
|
|
tuic,
|
|
anytls,
|
|
socks,
|
|
naive,
|
|
http,
|
|
mieru,
|
|
]);
|
|
|
|
export const formSchema = z.object({
|
|
name: z.string().min(1),
|
|
address: z.string().min(1),
|
|
country: z.string().optional(),
|
|
city: z.string().optional(),
|
|
protocols: z.array(protocolApiScheme),
|
|
});
|