92 lines
2.7 KiB
TypeScript
92 lines
2.7 KiB
TypeScript
export interface RemoteCliOptions {
|
|
host: string | null;
|
|
user: string;
|
|
port: number;
|
|
projectRoot: string;
|
|
identityFile: string | null;
|
|
transport: "auto" | "frontend" | "ssh";
|
|
args: string[];
|
|
}
|
|
|
|
const hostOptions = new Set(["--main-server-ip", "--main-server", "--server"]);
|
|
const userOptions = new Set(["--main-server-user", "--server-user"]);
|
|
const portOptions = new Set(["--main-server-port", "--server-port"]);
|
|
const rootOptions = new Set(["--main-server-root", "--server-root"]);
|
|
const keyOptions = new Set(["--main-server-key", "--server-key"]);
|
|
const transportOptions = new Set(["--main-server-transport", "--server-transport"]);
|
|
|
|
function positivePort(raw: string, option: string): number {
|
|
const value = Number(raw);
|
|
if (!Number.isInteger(value) || value <= 0 || value > 65535) throw new Error(`${option} must be a TCP port from 1 to 65535`);
|
|
return value;
|
|
}
|
|
|
|
function requiredValue(argv: string[], index: number, option: string): string {
|
|
const value = argv[index + 1];
|
|
if (value === undefined || value.length === 0) throw new Error(`${option} requires a non-empty value`);
|
|
return value;
|
|
}
|
|
|
|
function transportValue(raw: string, option: string): RemoteCliOptions["transport"] {
|
|
if (raw === "auto" || raw === "frontend" || raw === "ssh") return raw;
|
|
throw new Error(`${option} must be one of: auto, frontend, ssh`);
|
|
}
|
|
|
|
export function extractRemoteCliOptions(argv: string[]): RemoteCliOptions {
|
|
const rest: string[] = [];
|
|
const options: RemoteCliOptions = {
|
|
host: null,
|
|
user: "root",
|
|
port: 22,
|
|
projectRoot: "/root/unidesk",
|
|
identityFile: null,
|
|
transport: "auto",
|
|
args: rest,
|
|
};
|
|
|
|
for (let index = 0; index < argv.length; index += 1) {
|
|
const arg = argv[index] ?? "";
|
|
if (arg === "--") {
|
|
if (rest.length === 0) {
|
|
rest.push(...argv.slice(index + 1));
|
|
break;
|
|
}
|
|
rest.push(arg);
|
|
continue;
|
|
}
|
|
if (hostOptions.has(arg)) {
|
|
options.host = requiredValue(argv, index, arg);
|
|
index += 1;
|
|
continue;
|
|
}
|
|
if (userOptions.has(arg)) {
|
|
options.user = requiredValue(argv, index, arg);
|
|
index += 1;
|
|
continue;
|
|
}
|
|
if (portOptions.has(arg)) {
|
|
options.port = positivePort(requiredValue(argv, index, arg), arg);
|
|
index += 1;
|
|
continue;
|
|
}
|
|
if (rootOptions.has(arg)) {
|
|
options.projectRoot = requiredValue(argv, index, arg);
|
|
index += 1;
|
|
continue;
|
|
}
|
|
if (keyOptions.has(arg)) {
|
|
options.identityFile = requiredValue(argv, index, arg);
|
|
index += 1;
|
|
continue;
|
|
}
|
|
if (transportOptions.has(arg)) {
|
|
options.transport = transportValue(requiredValue(argv, index, arg), arg);
|
|
index += 1;
|
|
continue;
|
|
}
|
|
rest.push(arg);
|
|
}
|
|
|
|
return options;
|
|
}
|