128 lines
17 KiB
JavaScript
128 lines
17 KiB
JavaScript
|
"use strict";
|
||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
exports.execPowershell = exports.exec = exports.execFile = void 0;
|
||
|
const child_process_1 = __importDefault(require("child_process"));
|
||
|
const fs_1 = __importDefault(require("fs"));
|
||
|
const os_1 = __importDefault(require("os"));
|
||
|
const path_1 = __importDefault(require("path"));
|
||
|
const del_1 = __importDefault(require("del"));
|
||
|
const execa_1 = __importDefault(require("execa"));
|
||
|
const fs_extra_1 = require("fs-extra");
|
||
|
const os_family_1 = __importDefault(require("os-family"));
|
||
|
const nanoid_1 = require("nanoid");
|
||
|
const promisify_1 = __importDefault(require("./promisify"));
|
||
|
const binaries_1 = __importDefault(require("../binaries"));
|
||
|
const flatten_whitespace_1 = __importDefault(require("./flatten-whitespace"));
|
||
|
const get_environment_variable_1 = __importDefault(require("./get-environment-variable"));
|
||
|
const errors_1 = require("../errors");
|
||
|
const EXIT_CODE_REGEXP = /Exit code: (-?\d+)/;
|
||
|
const OPEN_PATH = '/usr/bin/open';
|
||
|
const TEMP_PIPE_NAME = seed => `testcafe-browser-tools-fifo-${seed}`;
|
||
|
const WINDOWS_DIR = get_environment_variable_1.default('SystemRoot') || 'C:\\Windows';
|
||
|
const SYSTEM32_DIR = path_1.default.join(WINDOWS_DIR, 'System32');
|
||
|
const CHCP_COM = path_1.default.join(SYSTEM32_DIR, 'chcp.com');
|
||
|
const POWERSHELL_DIR = path_1.default.join(SYSTEM32_DIR, 'WindowsPowerShell\\v1.0');
|
||
|
const POWERSHELL_BINARY = path_1.default.join(POWERSHELL_DIR, 'powershell.exe');
|
||
|
const POWERSHELL_ARGS = ['-NoProfile', '-NoLogo', '-NonInteractive', '-Command'];
|
||
|
const POWERSHELL_COMMAND_WRAPPER = command => flatten_whitespace_1.default `
|
||
|
$cp = (${CHCP_COM} | Select-String '\d+').Matches.Value;
|
||
|
Try
|
||
|
{
|
||
|
${CHCP_COM} 65001;
|
||
|
${command};
|
||
|
}
|
||
|
Finally
|
||
|
{
|
||
|
${CHCP_COM} $cp;
|
||
|
}
|
||
|
`;
|
||
|
function getTempPipePath() {
|
||
|
return path_1.default.join(os_1.default.tmpdir(), TEMP_PIPE_NAME(nanoid_1.nanoid()));
|
||
|
}
|
||
|
var execFilePromise = promisify_1.default(child_process_1.default.execFile);
|
||
|
var execPromise = promisify_1.default(child_process_1.default.exec);
|
||
|
function readPipe(pipePath) {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
let data = '';
|
||
|
const stream = fs_1.default.createReadStream(pipePath);
|
||
|
stream.on('data', newData => {
|
||
|
data += newData ? newData.toString() : '';
|
||
|
});
|
||
|
stream.on('end', () => resolve(data));
|
||
|
stream.on('error', reject);
|
||
|
});
|
||
|
}
|
||
|
function spawnApp(pipePath, binaryPath, args) {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
const child = child_process_1.default.spawn(OPEN_PATH, ['-n', '-a', binaries_1.default.app, '--args', binaries_1.default.main, pipePath, binaryPath, ...args]);
|
||
|
let outputData = '';
|
||
|
child.on('error', reject);
|
||
|
child.on('exit', code => {
|
||
|
if (code)
|
||
|
reject(new errors_1.NativeBinaryHasFailedError({ binary: binaryPath, exitCode: code, output: outputData }));
|
||
|
else
|
||
|
resolve();
|
||
|
});
|
||
|
function dataHandler(data) {
|
||
|
outputData += String(data);
|
||
|
}
|
||
|
child.stdout.on('data', dataHandler);
|
||
|
child.stderr.on('data', dataHandler);
|
||
|
});
|
||
|
}
|
||
|
async function runWithMacApp(binaryPath, args) {
|
||
|
if (!await fs_extra_1.pathExists(binaries_1.default.appDir)) {
|
||
|
await fs_extra_1.ensureDir(binaries_1.default.appDir);
|
||
|
await fs_extra_1.copy(binaries_1.default.appLocalDir, binaries_1.default.appDir);
|
||
|
}
|
||
|
const pipePath = getTempPipePath();
|
||
|
await execPromise(`mkfifo ${pipePath}`);
|
||
|
try {
|
||
|
const [data] = await Promise.all([
|
||
|
readPipe(pipePath),
|
||
|
spawnApp(pipePath, binaryPath, args)
|
||
|
]);
|
||
|
const exitCodeMatch = data.match(EXIT_CODE_REGEXP);
|
||
|
if (!exitCodeMatch)
|
||
|
return data;
|
||
|
const exitCode = Number(exitCodeMatch[1]);
|
||
|
if (exitCode)
|
||
|
throw new errors_1.NativeBinaryHasFailedError({ binary: binaryPath, output: data, exitCode });
|
||
|
return data;
|
||
|
}
|
||
|
finally {
|
||
|
await del_1.default(pipePath, { force: true });
|
||
|
}
|
||
|
}
|
||
|
//API
|
||
|
async function execFile(filePath, args) {
|
||
|
try {
|
||
|
if (os_family_1.default.mac)
|
||
|
return await runWithMacApp(filePath, args);
|
||
|
return await execFilePromise(filePath, args);
|
||
|
}
|
||
|
catch (err) {
|
||
|
if (err instanceof errors_1.NativeBinaryHasFailedError)
|
||
|
throw err;
|
||
|
const errorCode = err.status || err.code;
|
||
|
if (errorCode === void 0 || typeof errorCode === 'string')
|
||
|
throw err;
|
||
|
throw new errors_1.NativeBinaryHasFailedError({ binary: filePath, exitCode: errorCode });
|
||
|
}
|
||
|
}
|
||
|
exports.execFile = execFile;
|
||
|
async function exec(command) {
|
||
|
return execPromise(command, { env: process.env });
|
||
|
}
|
||
|
exports.exec = exec;
|
||
|
async function execPowershell(command) {
|
||
|
const wrappedCommand = POWERSHELL_COMMAND_WRAPPER(command);
|
||
|
// NOTE: We have to ignore stdin due to a problem with PowerShell 2.0
|
||
|
// See https://stackoverflow.com/a/9157170/11818061 for details.
|
||
|
return execa_1.default(POWERSHELL_BINARY, [...POWERSHELL_ARGS, wrappedCommand], { stdin: 'ignore' });
|
||
|
}
|
||
|
exports.execPowershell = execPowershell;
|
||
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9leGVjLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLGtFQUFzQztBQUN0Qyw0Q0FBb0I7QUFDcEIsNENBQW9CO0FBQ3BCLGdEQUF3QjtBQUN4Qiw4Q0FBc0I7QUFDdEIsa0RBQTBCO0FBQzFCLHVDQUF1RDtBQUN2RCwwREFBMkI7QUFDM0IsbUNBQWdDO0FBQ2hDLDREQUFvQztBQUNwQywyREFBbUM7QUFDbkMsOEVBQXFEO0FBQ3JELDBGQUFnRTtBQUNoRSxzQ0FBdUQ7QUFHdkQsTUFBTSxnQkFBZ0IsR0FBRyxvQkFBb0IsQ0FBQztBQUU5QyxNQUFNLFNBQVMsR0FBUSxlQUFlLENBQUM7QUFDdkMsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQywrQkFBK0IsSUFBSSxFQUFFLENBQUM7QUFFckUsTUFBTSxXQUFXLEdBQVMsa0NBQXNCLENBQUMsWUFBWSxDQUFDLElBQUksYUFBYSxDQUFDO0FBQ2hGLE1BQU0sWUFBWSxHQUFRLGNBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQzdELE1BQU0sUUFBUSxHQUFZLGNBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQzlELE1BQU0sY0FBYyxHQUFNLGNBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLHlCQUF5QixDQUFDLENBQUM7QUFDN0UsTUFBTSxpQkFBaUIsR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO0FBQ3RFLE1BQU0sZUFBZSxHQUFLLENBQUMsWUFBWSxFQUFFLFNBQVMsRUFBRSxpQkFBaUIsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUVuRixNQUFNLDBCQUEwQixHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUMsNEJBQWlCLENBQUM7YUFDbkQsUUFBUTs7O1VBR1gsUUFB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
|