update:
This commit is contained in:
114
src/cli.js
114
src/cli.js
@@ -10,6 +10,23 @@ const DEFAULT_FRP_ARCH = "amd64";
|
||||
const DEFAULT_FRP_SERVER_ADDR = "81.70.134.9";
|
||||
const DEFAULT_FRP_SERVER_PORT = 15443;
|
||||
const DEFAULT_SERVICE_NAME = "frpc";
|
||||
const NVM_INSTALL_VERSION = "v0.40.4";
|
||||
const NVM_INSTALL_COMMAND = `set -euo pipefail
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
if [ ! -s "$NVM_DIR/nvm.sh" ]; then
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_INSTALL_VERSION}/install.sh | bash
|
||||
elif command -v wget >/dev/null 2>&1; then
|
||||
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_INSTALL_VERSION}/install.sh | bash
|
||||
else
|
||||
echo "curl or wget is required to install nvm" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
. "$NVM_DIR/nvm.sh"
|
||||
nvm install --lts
|
||||
nvm alias default 'lts/*'
|
||||
nvm use --lts`;
|
||||
|
||||
function main(argv) {
|
||||
const parsed = parseArgs(argv);
|
||||
@@ -95,13 +112,14 @@ function handleFrp(action, argv, rootFlags, runner) {
|
||||
function installZsh(runner, flags) {
|
||||
runner.run("sudo", ["apt", "update"]);
|
||||
runner.run("sudo", ["apt", "upgrade", "-y"]);
|
||||
runner.run("sudo", ["apt", "install", "zsh", "git", "curl", "-y"]);
|
||||
runner.run("sudo", ["apt", "install", "zsh", "git", "curl", "wget", "-y"]);
|
||||
runner.run("chsh", ["-s", "/bin/zsh"]);
|
||||
|
||||
runner.run("sh", [
|
||||
"-c",
|
||||
'RUNZSH=no CHSH=no KEEP_ZSHRC=yes sh -c "$(curl -fsSL https://gitee.com/pocmon/ohmyzsh/raw/master/tools/install.sh)"',
|
||||
]);
|
||||
runner.run("bash", ["-c", NVM_INSTALL_COMMAND]);
|
||||
|
||||
const customDir = process.env.ZSH_CUSTOM || path.join(os.homedir(), ".oh-my-zsh", "custom");
|
||||
installGitPlugin(
|
||||
@@ -175,8 +193,9 @@ function installFrp(runner, flags) {
|
||||
function initFrpConfig(flags, runner) {
|
||||
const configPath = getConfigPath(flags);
|
||||
const force = Boolean(flags.force);
|
||||
const configExists = fs.existsSync(configPath);
|
||||
|
||||
if (fs.existsSync(configPath) && !force) {
|
||||
if (configExists && !force) {
|
||||
console.log(`${configPath} already exists. Use --force to rewrite it.`);
|
||||
return;
|
||||
}
|
||||
@@ -186,16 +205,24 @@ function initFrpConfig(flags, runner) {
|
||||
throw new Error("frp token is required. Pass --token <value> or set FRP_TOKEN.");
|
||||
}
|
||||
|
||||
const proxies = configExists && force
|
||||
? [...parseFrpConfig(fs.readFileSync(configPath, "utf8")).sections.values()].map((section) => ({
|
||||
name: section.name,
|
||||
...section.values,
|
||||
}))
|
||||
: [];
|
||||
|
||||
const config = renderFrpConfig({
|
||||
server_addr: stringFlag(flags, "server-addr", DEFAULT_FRP_SERVER_ADDR),
|
||||
server_port: numberFlag(flags, "server-port", DEFAULT_FRP_SERVER_PORT),
|
||||
token,
|
||||
tls_enable: booleanFlag(flags, "tls-enable", false),
|
||||
tcp_mux: booleanFlag(flags, "tcp-mux", true),
|
||||
log_file: stringFlag(flags, "log-file", "/var/log/frpc.log"),
|
||||
log_level: stringFlag(flags, "log-level", "info"),
|
||||
log_max_days: numberFlag(flags, "log-max-days", 7),
|
||||
}, []);
|
||||
serverAddr: stringFlag(flags, "server-addr", DEFAULT_FRP_SERVER_ADDR),
|
||||
serverPort: numberFlag(flags, "server-port", DEFAULT_FRP_SERVER_PORT),
|
||||
"auth.method": "token",
|
||||
"auth.token": token,
|
||||
"transport.tls.enable": booleanFlag(flags, "tls-enable", false),
|
||||
"transport.tcpMux": booleanFlag(flags, "tcp-mux", true),
|
||||
"log.to": stringFlag(flags, "log-file", "/var/log/frpc.log"),
|
||||
"log.level": stringFlag(flags, "log-level", "info"),
|
||||
"log.maxDays": numberFlag(flags, "log-max-days", 7),
|
||||
}, proxies);
|
||||
|
||||
writeFile(configPath, config, runner);
|
||||
}
|
||||
@@ -300,6 +327,12 @@ function parseFrpConfig(text) {
|
||||
let current = null;
|
||||
|
||||
for (const line of text.split(/\r?\n/)) {
|
||||
const proxyMatch = line.match(/^\s*\[\[proxies\]\]\s*$/);
|
||||
if (proxyMatch) {
|
||||
current = { name: "", values: {} };
|
||||
continue;
|
||||
}
|
||||
|
||||
const sectionMatch = line.match(/^\s*\[([A-Za-z0-9_.-]+)]\s*$/);
|
||||
if (sectionMatch) {
|
||||
current = { name: sectionMatch[1], values: {} };
|
||||
@@ -308,19 +341,65 @@ function parseFrpConfig(text) {
|
||||
}
|
||||
|
||||
if (!current) {
|
||||
globals.push(line);
|
||||
globals.push(migrateFrpGlobalLine(line));
|
||||
continue;
|
||||
}
|
||||
|
||||
const keyValue = parseTomlKeyValue(line);
|
||||
if (keyValue) {
|
||||
current.values[keyValue.key] = keyValue.value;
|
||||
applyProxyConfigValue(current, keyValue, sections);
|
||||
}
|
||||
}
|
||||
|
||||
return { globals: trimTrailingBlankLines(globals), sections };
|
||||
}
|
||||
|
||||
function migrateFrpGlobalLine(line) {
|
||||
const keyMap = {
|
||||
server_addr: "serverAddr",
|
||||
server_port: "serverPort",
|
||||
token: "auth.token",
|
||||
tls_enable: "transport.tls.enable",
|
||||
tcp_mux: "transport.tcpMux",
|
||||
log_file: "log.to",
|
||||
log_level: "log.level",
|
||||
log_max_days: "log.maxDays",
|
||||
};
|
||||
const match = line.match(/^(\s*)([A-Za-z0-9_.-]+)(\s*=.*)$/);
|
||||
if (!match) {
|
||||
return line;
|
||||
}
|
||||
|
||||
const [, indent, key, rest] = match;
|
||||
return `${indent}${keyMap[key] || key}${rest}`;
|
||||
}
|
||||
|
||||
function applyProxyConfigValue(current, keyValue, sections) {
|
||||
const key = normalizeProxyKey(keyValue.key);
|
||||
|
||||
if (key === "name") {
|
||||
if (current.name) {
|
||||
sections.delete(current.name);
|
||||
}
|
||||
|
||||
current.name = String(keyValue.value);
|
||||
sections.set(current.name, current);
|
||||
return;
|
||||
}
|
||||
|
||||
current.values[key] = keyValue.value;
|
||||
}
|
||||
|
||||
function normalizeProxyKey(key) {
|
||||
const keyMap = {
|
||||
localIP: "local_ip",
|
||||
localPort: "local_port",
|
||||
remotePort: "remote_port",
|
||||
};
|
||||
|
||||
return keyMap[key] || key;
|
||||
}
|
||||
|
||||
function parseTomlKeyValue(line) {
|
||||
const withoutComment = line.replace(/\s+#.*$/, "").trim();
|
||||
const match = withoutComment.match(/^([A-Za-z0-9_.-]+)\s*=\s*(.+)$/);
|
||||
@@ -374,11 +453,12 @@ function renderFrpConfig(globals, proxies) {
|
||||
}
|
||||
|
||||
function renderProxy(name, values) {
|
||||
return `[${name}]
|
||||
return `[[proxies]]
|
||||
name = ${formatTomlValue(name)}
|
||||
type = ${formatTomlValue(values.type || "tcp")}
|
||||
local_ip = ${formatTomlValue(values.local_ip || "127.0.0.1")}
|
||||
local_port = ${formatTomlValue(values.local_port)}
|
||||
remote_port = ${formatTomlValue(values.remote_port)}
|
||||
localIP = ${formatTomlValue(values.local_ip || "127.0.0.1")}
|
||||
localPort = ${formatTomlValue(values.local_port)}
|
||||
remotePort = ${formatTomlValue(values.remote_port)}
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user