import * as readline from "readline"; import { execFileSync, ExecFileSyncOptions } from "child_process"; import tmp from "tmp"; import createDebug from "debug"; import path from "path"; import sudoPrompt from "sudo-prompt"; import { configPath } from "./constants"; const debug = createDebug("devcert:util"); export function openssl(args: string[]) { return run("openssl", args, { stdio: "pipe", env: Object.assign( { RANDFILE: path.join(configPath(".rnd")), }, process.env ), }); } export function run( cmd: string, args: string[], options: ExecFileSyncOptions = {} ) { debug(`execFileSync: \`${cmd} ${args.join(" ")}\``); return execFileSync(cmd, args, options); } export function sudoAppend(file: string, input: ExecFileSyncOptions["input"]) { run("sudo", ["tee", "-a", file], { input, }); } export function waitForUser(): Promise { const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); return new Promise((resolve) => { // Set raw mode to capture all keypresses readline.emitKeypressEvents(process.stdin); process.stdin.setRawMode(true); // Listen for keypress event process.stdin.once("keypress", () => { // Restore terminal settings process.stdin.setRawMode(false); rl.close(); resolve(); }); }); } export function reportableError(message: string) { return new Error( `${message} | This is a bug in devcert, please report the issue at https://github.com/davewasmer/devcert/issues` ); } export function mktmp() { // discardDescriptor because windows complains the file is in use if we create a tmp file // and then shell out to a process that tries to use it return tmp.fileSync({ discardDescriptor: true }).name; } export function sudo(cmd: string): Promise { return new Promise((resolve, reject) => { sudoPrompt.exec( cmd, { name: "devcert" }, (err: Error | null, stdout: string | null, stderr: string | null) => { let error = err || (typeof stderr === "string" && stderr.trim().length > 0 && new Error(stderr)); error ? reject(error) : resolve(stdout); } ); }); } export const numericHash = (str: string): number => { let hash = 5381; let i = str.length; while (i) { hash = (hash * 33) ^ str.charCodeAt(--i); } return hash >>> 0; };