Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
125 lines
3.3 KiB
TypeScript
125 lines
3.3 KiB
TypeScript
/**
|
|
* Port Forwarding utilities and constants
|
|
*/
|
|
import type { PortForwardingRule, PortForwardingType } from '../../domain/models';
|
|
|
|
const TYPE_LABEL_KEYS: Record<PortForwardingType, string> = {
|
|
local: 'pf.type.local',
|
|
remote: 'pf.type.remote',
|
|
dynamic: 'pf.type.dynamic',
|
|
};
|
|
|
|
const TYPE_MENU_LABEL_KEYS: Record<PortForwardingType, string> = {
|
|
local: 'pf.type.menu.local',
|
|
remote: 'pf.type.menu.remote',
|
|
dynamic: 'pf.type.menu.dynamic',
|
|
};
|
|
|
|
const TYPE_DESCRIPTION_KEYS: Record<PortForwardingType, string> = {
|
|
local: 'pf.type.local.desc',
|
|
remote: 'pf.type.remote.desc',
|
|
dynamic: 'pf.type.dynamic.desc',
|
|
};
|
|
|
|
export function getTypeLabel(
|
|
t: (key: string, vars?: Record<string, unknown>) => string,
|
|
type: PortForwardingType
|
|
): string {
|
|
return t(TYPE_LABEL_KEYS[type]);
|
|
}
|
|
|
|
export function getTypeMenuLabel(
|
|
t: (key: string, vars?: Record<string, unknown>) => string,
|
|
type: PortForwardingType
|
|
): string {
|
|
return t(TYPE_MENU_LABEL_KEYS[type]);
|
|
}
|
|
|
|
export function getTypeDescription(
|
|
t: (key: string, vars?: Record<string, unknown>) => string,
|
|
type: PortForwardingType
|
|
): string {
|
|
return t(TYPE_DESCRIPTION_KEYS[type]);
|
|
}
|
|
|
|
export function buildRuleSummary(
|
|
t: (key: string, vars?: Record<string, unknown>) => string,
|
|
rule: PortForwardingRule
|
|
): string {
|
|
const vars = {
|
|
bindAddress: rule.bindAddress,
|
|
localPort: rule.localPort,
|
|
remoteHost: rule.remoteHost,
|
|
remotePort: rule.remotePort,
|
|
};
|
|
|
|
switch (rule.type) {
|
|
case 'local':
|
|
return t('pf.rule.summary.local', vars);
|
|
case 'remote':
|
|
return t('pf.rule.summary.remote', vars);
|
|
case 'dynamic':
|
|
return t('pf.rule.summary.dynamic', vars);
|
|
default:
|
|
return t('pf.rule.summary.local', vars);
|
|
}
|
|
}
|
|
|
|
export async function stopRuntimeTunnelBeforeDelete(
|
|
ruleId: string,
|
|
stopTunnel: (ruleId: string) => Promise<{ success: boolean }>,
|
|
): Promise<boolean> {
|
|
return (await stopTunnel(ruleId)).success;
|
|
}
|
|
|
|
/**
|
|
* Get status color class for a rule
|
|
*/
|
|
export function getStatusColor(status: string): string {
|
|
switch (status) {
|
|
case 'active':
|
|
return 'bg-emerald-500';
|
|
case 'connecting':
|
|
return 'bg-yellow-500 animate-pulse';
|
|
case 'error':
|
|
return 'bg-red-500';
|
|
case 'unknown':
|
|
return 'bg-muted-foreground/60 animate-pulse';
|
|
default:
|
|
return 'bg-muted-foreground/40';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get type badge color class
|
|
*/
|
|
export function getTypeColor(type: PortForwardingType, isActive: boolean): string {
|
|
const colors = {
|
|
local: isActive ? 'bg-sky-500 text-white' : 'bg-sky-600 text-white dark:bg-sky-400 dark:text-slate-950',
|
|
remote: isActive ? 'bg-indigo-500 text-white' : 'bg-indigo-600 text-white dark:bg-indigo-400 dark:text-slate-950',
|
|
dynamic: isActive ? 'bg-violet-500 text-white' : 'bg-violet-600 text-white dark:bg-violet-400 dark:text-slate-950',
|
|
};
|
|
return colors[type];
|
|
}
|
|
|
|
/**
|
|
* Generate default label for a rule
|
|
*/
|
|
export function generateRuleLabel(
|
|
type: PortForwardingType,
|
|
localPort?: number,
|
|
remoteHost?: string,
|
|
remotePort?: number
|
|
): string {
|
|
switch (type) {
|
|
case 'local':
|
|
return `Local:${localPort} -> ${remoteHost}:${remotePort}`;
|
|
case 'remote':
|
|
return `Remote:${localPort} -> ${remoteHost}:${remotePort}`;
|
|
case 'dynamic':
|
|
return `SOCKS:${localPort}`;
|
|
default:
|
|
return 'New Rule';
|
|
}
|
|
}
|