Files
Netcatty/domain/proxyProfiles.ts
2026-06-05 15:35:21 +08:00

108 lines
3.2 KiB
TypeScript

import type { GroupConfig, Host, ProxyConfig, ProxyProfile } from "./models";
const cloneProxyConfig = (config: ProxyConfig): ProxyConfig => ({
...config,
});
export const isValidProxyPort = (port: unknown): boolean => {
const value = Number(port);
return Number.isInteger(value) && value >= 1 && value <= 65535;
};
export const isProxyCommandConfig = (config: ProxyConfig | undefined): boolean => {
return config?.type === "command";
};
export const isEmptyProxyConfigDraft = (config: ProxyConfig | undefined): boolean => {
if (!config) return true;
if (isProxyCommandConfig(config)) return !config.command?.trim();
return !config.host.trim() && !config.username?.trim() && !config.password?.trim();
};
export const isCompleteProxyConfig = (config: ProxyConfig | undefined): boolean => {
if (isProxyCommandConfig(config)) return Boolean(config?.command?.trim());
return Boolean(config?.host.trim()) && isValidProxyPort(config?.port);
};
export const normalizeManualProxyConfig = (
config: ProxyConfig | undefined,
): ProxyConfig | undefined => {
if (!config || isEmptyProxyConfigDraft(config)) return undefined;
if (isProxyCommandConfig(config)) {
return {
type: "command",
host: "",
port: 0,
command: config.command?.trim(),
};
}
return {
...config,
host: config.host.trim(),
username: config.username?.trim() || undefined,
password: config.password || undefined,
};
};
export const hasUsableProxyConfig = (config: ProxyConfig | undefined): boolean => {
return isCompleteProxyConfig(config);
};
export const formatProxyConfigEndpoint = (config: ProxyConfig | undefined): string => {
if (!config) return "";
if (isProxyCommandConfig(config)) return "ProxyCommand";
return `${config.host}:${config.port}`;
};
export const formatProxyConfigType = (config: ProxyConfig | undefined): string => {
if (!config) return "";
if (isProxyCommandConfig(config)) return "ProxyCommand";
return config.type.toUpperCase();
};
export function findProxyProfile(
proxyProfileId: string | undefined,
proxyProfiles: ProxyProfile[],
): ProxyProfile | undefined {
if (!proxyProfileId) return undefined;
return proxyProfiles.find((profile) => profile.id === proxyProfileId);
}
export function materializeHostProxyProfile<T extends Host>(
host: T,
proxyProfiles: ProxyProfile[],
): T {
if (host.proxyConfig || !host.proxyProfileId) return host;
const profile = findProxyProfile(host.proxyProfileId, proxyProfiles);
if (!profile) return host;
return {
...host,
proxyConfig: cloneProxyConfig(profile.config),
};
}
const clearProxyProfileId = <T extends { proxyProfileId?: string }>(
item: T,
proxyProfileId: string,
): T => {
if (item.proxyProfileId !== proxyProfileId) return item;
const { proxyProfileId: _proxyProfileId, ...rest } = item;
return rest as T;
};
export function removeProxyProfileReferences(
proxyProfileId: string,
data: {
hosts: Host[];
groupConfigs: GroupConfig[];
},
): {
hosts: Host[];
groupConfigs: GroupConfig[];
} {
return {
hosts: data.hosts.map((host) => clearProxyProfileId(host, proxyProfileId)),
groupConfigs: data.groupConfigs.map((config) => clearProxyProfileId(config, proxyProfileId)),
};
}