Files

71 lines
2.5 KiB
TypeScript

import { shellQuote } from "./curl";
/** The shells the terminal environment is written for */
export type TerminalShell = "posix" | "fish" | "powershell" | "cmd";
export const TERMINAL_SHELLS: { value: TerminalShell; label: string }[] = [
{ value: "posix", label: "bash / zsh" },
{ value: "fish", label: "fish" },
{ value: "powershell", label: "PowerShell" },
{ value: "cmd", label: "cmd" },
];
/** The shell a platform's terminal opens by default */
export function defaultShell(osType: string | null | undefined): TerminalShell {
return osType === "windows" ? "powershell" : "posix";
}
/**
* The variables that send one terminal's traffic through the proxy on `port` and trust its CA
* at `caPath`, for tools that read neither the system proxy nor the login keychain: Node,
* Python, and anything built on OpenSSL.
*/
export function environmentVars(port: number, caPath: string): [string, string][] {
const proxy = `http://127.0.0.1:${port}`;
return [
["HTTP_PROXY", proxy],
["HTTPS_PROXY", proxy],
// curl reads only the lowercase name for plain HTTP.
["http_proxy", proxy],
["https_proxy", proxy],
["SSL_CERT_FILE", caPath],
["NODE_EXTRA_CA_CERTS", caPath],
["REQUESTS_CA_BUNDLE", caPath],
];
}
/** The variables as `shell` sets them, one a line */
export function environmentBlock(shell: TerminalShell, port: number, caPath: string): string {
return environmentVars(port, caPath)
.map(([name, value]) => setLine(shell, name, value))
.join("\n");
}
function setLine(shell: TerminalShell, name: string, value: string): string {
switch (shell) {
case "posix":
return `export ${name}=${SAFE.test(value) ? value : shellQuote(value)}`;
case "fish":
return `set -gx ${name} ${fishQuote(value)}`;
case "powershell":
return `$env:${name} = '${value.replaceAll("'", "''")}'`;
case "cmd":
// The quotes around the pair keep spaces and stop at the closing one, unlike `set A="b"`
return `set "${name}=${value}"`;
}
}
/** Needs no quotes in any POSIX shell or fish */
const SAFE = /^[\w@%+=:,./-]+$/;
/** Fish quotes like the POSIX shells, except a backslash and a quote escape inside single quotes */
function fishQuote(value: string): string {
if (SAFE.test(value)) return value;
return `'${value.replaceAll("\\", "\\\\").replaceAll("'", "\\'")}'`;
}
/** Shell exports for bash and zsh, as the palette and Settings copy them */
export function environmentExports(port: number, caPath: string): string {
return environmentBlock("posix", port, caPath);
}