@mcesystems/apple-kit 1.0.40 → 1.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +150 -185
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +150 -184
- package/dist/index.mjs.map +4 -4
- package/dist/types/logic/actions/device.d.ts +1 -6
- package/dist/types/logic/actions/device.d.ts.map +1 -1
- package/dist/types/logic/actions/install.d.ts.map +1 -1
- package/dist/types/logic/actions/pair.d.ts.map +1 -1
- package/dist/types/logic/actions/proxy.d.ts.map +1 -1
- package/dist/types/logic/actions/restore.d.ts +36 -0
- package/dist/types/logic/actions/restore.d.ts.map +1 -0
- package/dist/types/logic/actions/tool.d.ts +8 -0
- package/dist/types/logic/actions/tool.d.ts.map +1 -0
- package/dist/types/logic/utils/resolvePath.d.ts +11 -0
- package/dist/types/logic/utils/resolvePath.d.ts.map +1 -0
- package/package.json +1 -1
- package/prebuilt/libimobiledevice-windows-v1.0.0.tar.gz +0 -0
- package/scripts/build-windows.sh.template +222 -166
- package/scripts/export-resources.mts +859 -856
package/dist/index.mjs
CHANGED
|
@@ -940,46 +940,18 @@ function logInfo(message) {
|
|
|
940
940
|
function logTask(message) {
|
|
941
941
|
debugTask(message);
|
|
942
942
|
}
|
|
943
|
+
function logError(message) {
|
|
944
|
+
debugError(message);
|
|
945
|
+
}
|
|
943
946
|
|
|
944
|
-
// src/logic/actions/
|
|
947
|
+
// src/logic/actions/tool.ts
|
|
945
948
|
import { exec as execCallback } from "node:child_process";
|
|
946
|
-
import {
|
|
947
|
-
import { dirname, join } from "node:path";
|
|
949
|
+
import { join as join2 } from "node:path";
|
|
948
950
|
import { promisify } from "node:util";
|
|
949
951
|
|
|
950
|
-
// src/logic/
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
const lines = output.split("\n");
|
|
954
|
-
for (const line of lines) {
|
|
955
|
-
const colonIndex = line.indexOf(":");
|
|
956
|
-
if (colonIndex > 0) {
|
|
957
|
-
const key = line.substring(0, colonIndex).trim();
|
|
958
|
-
const value = line.substring(colonIndex + 1).trim();
|
|
959
|
-
result[key] = value;
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
return result;
|
|
963
|
-
}
|
|
964
|
-
function parseAppList(output) {
|
|
965
|
-
const apps = [];
|
|
966
|
-
const lines = output.trim().split("\n");
|
|
967
|
-
for (const line of lines) {
|
|
968
|
-
const match = line.match(/^([^,]+),\s*([^,]+),\s*"?([^"]+)"?/);
|
|
969
|
-
if (match) {
|
|
970
|
-
apps.push({
|
|
971
|
-
bundleId: match[1].trim(),
|
|
972
|
-
version: match[2].trim(),
|
|
973
|
-
displayName: match[3].trim(),
|
|
974
|
-
bundleVersion: ""
|
|
975
|
-
});
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
return apps;
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
// src/logic/actions/device.ts
|
|
982
|
-
var execAsync = promisify(execCallback);
|
|
952
|
+
// src/logic/utils/resolvePath.ts
|
|
953
|
+
import { existsSync } from "node:fs";
|
|
954
|
+
import { dirname, isAbsolute, join } from "node:path";
|
|
983
955
|
function getModuleDir() {
|
|
984
956
|
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
985
957
|
const { fileURLToPath } = __require("node:url");
|
|
@@ -987,56 +959,6 @@ function getModuleDir() {
|
|
|
987
959
|
}
|
|
988
960
|
return __dirname;
|
|
989
961
|
}
|
|
990
|
-
async function getDeviceInfo(udid) {
|
|
991
|
-
logTask(`Getting device info for ${udid}`);
|
|
992
|
-
const result = await runIDeviceTool("ideviceinfo", ["-u", udid]);
|
|
993
|
-
if (!result) {
|
|
994
|
-
throw new Error("Failed to get device info");
|
|
995
|
-
}
|
|
996
|
-
const props = parsePlistOutput(result.stdout);
|
|
997
|
-
return {
|
|
998
|
-
deviceName: props.DeviceName || "",
|
|
999
|
-
productType: props.ProductType || "",
|
|
1000
|
-
productVersion: props.ProductVersion || "",
|
|
1001
|
-
buildVersion: props.BuildVersion || "",
|
|
1002
|
-
serialNumber: props.SerialNumber || "",
|
|
1003
|
-
udid: props.UniqueDeviceID || udid,
|
|
1004
|
-
wifiAddress: props.WiFiAddress || "",
|
|
1005
|
-
bluetoothAddress: props.BluetoothAddress || "",
|
|
1006
|
-
phoneNumber: props.PhoneNumber || "",
|
|
1007
|
-
cpuArchitecture: props.CPUArchitecture || "",
|
|
1008
|
-
hardwareModel: props.HardwareModel || "",
|
|
1009
|
-
modelNumber: props.ModelNumber || "",
|
|
1010
|
-
regionInfo: props.RegionInfo || "",
|
|
1011
|
-
timeZone: props.TimeZone || "",
|
|
1012
|
-
uniqueChipID: props.UniqueChipID || "",
|
|
1013
|
-
isPaired: true
|
|
1014
|
-
// If we can get info, device is paired
|
|
1015
|
-
};
|
|
1016
|
-
}
|
|
1017
|
-
async function runIDeviceTool(toolName, args = [], options = {}) {
|
|
1018
|
-
const binPath = getIDeviceBinPath();
|
|
1019
|
-
const ext = process.platform === "win32" ? ".exe" : "";
|
|
1020
|
-
const toolPath = binPath ? join(binPath, `${toolName}${ext}`) : `${toolName}${ext}`;
|
|
1021
|
-
const command = `"${toolPath}" ${args.map((a) => `"${a}"`).join(" ")}`;
|
|
1022
|
-
return execIDevice(command, options);
|
|
1023
|
-
}
|
|
1024
|
-
async function execIDevice(command, options = {}) {
|
|
1025
|
-
const binPath = getIDeviceBinPath();
|
|
1026
|
-
if (binPath) {
|
|
1027
|
-
options.cwd = binPath;
|
|
1028
|
-
}
|
|
1029
|
-
const result = await execAsync(command, {
|
|
1030
|
-
...options,
|
|
1031
|
-
env: process.env,
|
|
1032
|
-
windowsHide: true,
|
|
1033
|
-
encoding: "utf8"
|
|
1034
|
-
});
|
|
1035
|
-
return {
|
|
1036
|
-
stdout: result.stdout.toString(),
|
|
1037
|
-
stderr: result.stderr.toString()
|
|
1038
|
-
};
|
|
1039
|
-
}
|
|
1040
962
|
function getPlatformDir() {
|
|
1041
963
|
const platform = process.platform;
|
|
1042
964
|
if (platform === "win32") {
|
|
@@ -1050,29 +972,19 @@ function getPlatformDir() {
|
|
|
1050
972
|
}
|
|
1051
973
|
return platform;
|
|
1052
974
|
}
|
|
1053
|
-
function getBundledResourcesPath() {
|
|
1054
|
-
const moduleDir = getModuleDir();
|
|
1055
|
-
let packageRoot;
|
|
1056
|
-
if (moduleDir.includes("dist")) {
|
|
1057
|
-
packageRoot = join(moduleDir, "..", "..");
|
|
1058
|
-
} else {
|
|
1059
|
-
packageRoot = join(moduleDir, "..", "..", "..", "..");
|
|
1060
|
-
}
|
|
1061
|
-
const platformDir = getPlatformDir();
|
|
1062
|
-
const distPath = join(packageRoot, "dist", "resources", "bin", platformDir);
|
|
1063
|
-
if (existsSync(join(distPath, "idevice_id")) || existsSync(join(distPath, "idevice_id.exe"))) {
|
|
1064
|
-
return distPath;
|
|
1065
|
-
}
|
|
1066
|
-
const devPath = join(packageRoot, "resources", "bin", platformDir);
|
|
1067
|
-
if (existsSync(join(devPath, "idevice_id")) || existsSync(join(devPath, "idevice_id.exe"))) {
|
|
1068
|
-
return devPath;
|
|
1069
|
-
}
|
|
1070
|
-
return null;
|
|
1071
|
-
}
|
|
1072
975
|
function getResourcesBinPath() {
|
|
1073
976
|
const envBinPath = process.env.IDeviceBinPath;
|
|
1074
977
|
if (envBinPath) {
|
|
1075
|
-
|
|
978
|
+
if (isAbsolute(envBinPath)) {
|
|
979
|
+
return envBinPath;
|
|
980
|
+
}
|
|
981
|
+
const absolutePath = join(process.cwd(), envBinPath);
|
|
982
|
+
logInfo(`Using absolute path: ${absolutePath}`);
|
|
983
|
+
if (existsSync(absolutePath)) {
|
|
984
|
+
return absolutePath;
|
|
985
|
+
}
|
|
986
|
+
logError(`Absolute path does not exist: ${absolutePath}`);
|
|
987
|
+
return "";
|
|
1076
988
|
}
|
|
1077
989
|
const bundledPath = getBundledResourcesPath();
|
|
1078
990
|
if (bundledPath) {
|
|
@@ -1098,8 +1010,50 @@ function getResourcesBinPath() {
|
|
|
1098
1010
|
}
|
|
1099
1011
|
return "";
|
|
1100
1012
|
}
|
|
1101
|
-
function
|
|
1102
|
-
|
|
1013
|
+
function getBundledResourcesPath() {
|
|
1014
|
+
const moduleDir = getModuleDir();
|
|
1015
|
+
let packageRoot;
|
|
1016
|
+
if (moduleDir.includes("dist")) {
|
|
1017
|
+
packageRoot = join(moduleDir, "..", "..");
|
|
1018
|
+
} else {
|
|
1019
|
+
packageRoot = join(moduleDir, "..", "..", "..", "..");
|
|
1020
|
+
}
|
|
1021
|
+
const platformDir = getPlatformDir();
|
|
1022
|
+
const distPath = join(packageRoot, "dist", "resources", "bin", platformDir);
|
|
1023
|
+
if (existsSync(join(distPath, "idevice_id")) || existsSync(join(distPath, "idevice_id.exe"))) {
|
|
1024
|
+
return distPath;
|
|
1025
|
+
}
|
|
1026
|
+
const devPath = join(packageRoot, "resources", "bin", platformDir);
|
|
1027
|
+
if (existsSync(join(devPath, "idevice_id")) || existsSync(join(devPath, "idevice_id.exe"))) {
|
|
1028
|
+
return devPath;
|
|
1029
|
+
}
|
|
1030
|
+
return null;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
// src/logic/actions/tool.ts
|
|
1034
|
+
var execAsync = promisify(execCallback);
|
|
1035
|
+
async function runIDeviceTool(toolName, args = [], options = {}) {
|
|
1036
|
+
const binPath = getResourcesBinPath();
|
|
1037
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
1038
|
+
const toolPath = binPath ? join2(binPath, `${toolName}${ext}`) : `${toolName}${ext}`;
|
|
1039
|
+
const command = `"${toolPath}" ${args.map((a) => `"${a}"`).join(" ")}`;
|
|
1040
|
+
return execIDevice(command, options);
|
|
1041
|
+
}
|
|
1042
|
+
async function execIDevice(command, options = {}) {
|
|
1043
|
+
const binPath = getResourcesBinPath();
|
|
1044
|
+
if (binPath) {
|
|
1045
|
+
options.cwd = binPath;
|
|
1046
|
+
}
|
|
1047
|
+
const result = await execAsync(command, {
|
|
1048
|
+
...options,
|
|
1049
|
+
env: process.env,
|
|
1050
|
+
windowsHide: true,
|
|
1051
|
+
encoding: "utf8"
|
|
1052
|
+
});
|
|
1053
|
+
return {
|
|
1054
|
+
stdout: result.stdout.toString(),
|
|
1055
|
+
stderr: result.stderr.toString()
|
|
1056
|
+
};
|
|
1103
1057
|
}
|
|
1104
1058
|
|
|
1105
1059
|
// src/logic/actions/activation.ts
|
|
@@ -1140,6 +1094,70 @@ async function activate(udid) {
|
|
|
1140
1094
|
}
|
|
1141
1095
|
}
|
|
1142
1096
|
|
|
1097
|
+
// src/logic/actions/device.ts
|
|
1098
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
1099
|
+
import { join as join3 } from "node:path";
|
|
1100
|
+
|
|
1101
|
+
// src/logic/dataParser.ts
|
|
1102
|
+
function parsePlistOutput(output) {
|
|
1103
|
+
const result = {};
|
|
1104
|
+
const lines = output.split("\n");
|
|
1105
|
+
for (const line of lines) {
|
|
1106
|
+
const colonIndex = line.indexOf(":");
|
|
1107
|
+
if (colonIndex > 0) {
|
|
1108
|
+
const key = line.substring(0, colonIndex).trim();
|
|
1109
|
+
const value = line.substring(colonIndex + 1).trim();
|
|
1110
|
+
result[key] = value;
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
return result;
|
|
1114
|
+
}
|
|
1115
|
+
function parseAppList(output) {
|
|
1116
|
+
const apps = [];
|
|
1117
|
+
const lines = output.trim().split("\n");
|
|
1118
|
+
for (const line of lines) {
|
|
1119
|
+
const match = line.match(/^([^,]+),\s*([^,]+),\s*"?([^"]+)"?/);
|
|
1120
|
+
if (match) {
|
|
1121
|
+
apps.push({
|
|
1122
|
+
bundleId: match[1].trim(),
|
|
1123
|
+
version: match[2].trim(),
|
|
1124
|
+
displayName: match[3].trim(),
|
|
1125
|
+
bundleVersion: ""
|
|
1126
|
+
});
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
return apps;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
// src/logic/actions/device.ts
|
|
1133
|
+
async function getDeviceInfo(udid) {
|
|
1134
|
+
logTask(`Getting device info for ${udid}`);
|
|
1135
|
+
const result = await runIDeviceTool("ideviceinfo", ["-u", udid]);
|
|
1136
|
+
if (!result) {
|
|
1137
|
+
throw new Error("Failed to get device info");
|
|
1138
|
+
}
|
|
1139
|
+
const props = parsePlistOutput(result.stdout);
|
|
1140
|
+
return {
|
|
1141
|
+
deviceName: props.DeviceName || "",
|
|
1142
|
+
productType: props.ProductType || "",
|
|
1143
|
+
productVersion: props.ProductVersion || "",
|
|
1144
|
+
buildVersion: props.BuildVersion || "",
|
|
1145
|
+
serialNumber: props.SerialNumber || "",
|
|
1146
|
+
udid: props.UniqueDeviceID || udid,
|
|
1147
|
+
wifiAddress: props.WiFiAddress || "",
|
|
1148
|
+
bluetoothAddress: props.BluetoothAddress || "",
|
|
1149
|
+
phoneNumber: props.PhoneNumber || "",
|
|
1150
|
+
cpuArchitecture: props.CPUArchitecture || "",
|
|
1151
|
+
hardwareModel: props.HardwareModel || "",
|
|
1152
|
+
modelNumber: props.ModelNumber || "",
|
|
1153
|
+
regionInfo: props.RegionInfo || "",
|
|
1154
|
+
timeZone: props.TimeZone || "",
|
|
1155
|
+
uniqueChipID: props.UniqueChipID || "",
|
|
1156
|
+
isPaired: true
|
|
1157
|
+
// If we can get info, device is paired
|
|
1158
|
+
};
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1143
1161
|
// src/logic/actions/pair.ts
|
|
1144
1162
|
async function isPaired(udid) {
|
|
1145
1163
|
logTask(`Checking pairing status for ${udid}`);
|
|
@@ -1160,10 +1178,14 @@ async function trustDevice(udid, timeout2 = 6e4, onWaitingForTrust) {
|
|
|
1160
1178
|
return true;
|
|
1161
1179
|
}
|
|
1162
1180
|
logInfo(`Initiating pairing for device ${udid}`);
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1181
|
+
try {
|
|
1182
|
+
const pairResult = await pair(udid);
|
|
1183
|
+
if (pairResult) {
|
|
1184
|
+
logInfo(`Device ${udid} paired successfully`);
|
|
1185
|
+
return true;
|
|
1186
|
+
}
|
|
1187
|
+
} catch (error) {
|
|
1188
|
+
logError(`Pairing failed with ${udid}: ${error}`);
|
|
1167
1189
|
}
|
|
1168
1190
|
logInfo("Please accept the trust dialog on the device...");
|
|
1169
1191
|
onWaitingForTrust?.();
|
|
@@ -1278,6 +1300,12 @@ async function launchApp(bundleId, args, udid) {
|
|
|
1278
1300
|
if (!await isPaired(udid)) {
|
|
1279
1301
|
await waitForPairing(udid, 1e4);
|
|
1280
1302
|
}
|
|
1303
|
+
const installed = await isAppInstalled(bundleId, udid);
|
|
1304
|
+
if (!installed) {
|
|
1305
|
+
throw new Error(
|
|
1306
|
+
`App "${bundleId}" is not installed on the device. Install the app first or verify the bundle identifier is correct.`
|
|
1307
|
+
);
|
|
1308
|
+
}
|
|
1281
1309
|
await wakeDevice(udid);
|
|
1282
1310
|
try {
|
|
1283
1311
|
logInfo(`Attempting to launch ${bundleId} using idevicedebug...`);
|
|
@@ -1405,82 +1433,13 @@ async function launchAppWithPymobiledevice3(bundleId, args, udid) {
|
|
|
1405
1433
|
|
|
1406
1434
|
// src/logic/actions/proxy.ts
|
|
1407
1435
|
import { spawn } from "node:child_process";
|
|
1408
|
-
import {
|
|
1409
|
-
import { dirname as dirname2, join as join2 } from "node:path";
|
|
1410
|
-
function getModuleDir2() {
|
|
1411
|
-
if (typeof import.meta !== "undefined" && import.meta.url) {
|
|
1412
|
-
const { fileURLToPath } = __require("node:url");
|
|
1413
|
-
return dirname2(fileURLToPath(import.meta.url));
|
|
1414
|
-
}
|
|
1415
|
-
return __dirname;
|
|
1416
|
-
}
|
|
1417
|
-
function getPlatformDir2() {
|
|
1418
|
-
const platform = process.platform;
|
|
1419
|
-
if (platform === "win32") {
|
|
1420
|
-
return "windows";
|
|
1421
|
-
}
|
|
1422
|
-
if (platform === "darwin") {
|
|
1423
|
-
return "darwin";
|
|
1424
|
-
}
|
|
1425
|
-
if (platform === "linux") {
|
|
1426
|
-
return "linux";
|
|
1427
|
-
}
|
|
1428
|
-
return platform;
|
|
1429
|
-
}
|
|
1430
|
-
function getBundledResourcesPath2() {
|
|
1431
|
-
const moduleDir = getModuleDir2();
|
|
1432
|
-
let packageRoot;
|
|
1433
|
-
if (moduleDir.includes("dist")) {
|
|
1434
|
-
packageRoot = join2(moduleDir, "..", "..");
|
|
1435
|
-
} else {
|
|
1436
|
-
packageRoot = join2(moduleDir, "..", "..", "..", "..");
|
|
1437
|
-
}
|
|
1438
|
-
const platformDir = getPlatformDir2();
|
|
1439
|
-
const distPath = join2(packageRoot, "dist", "resources", "bin", platformDir);
|
|
1440
|
-
if (existsSync2(join2(distPath, "iproxy")) || existsSync2(join2(distPath, "iproxy.exe"))) {
|
|
1441
|
-
return distPath;
|
|
1442
|
-
}
|
|
1443
|
-
const devPath = join2(packageRoot, "resources", "bin", platformDir);
|
|
1444
|
-
if (existsSync2(join2(devPath, "iproxy")) || existsSync2(join2(devPath, "iproxy.exe"))) {
|
|
1445
|
-
return devPath;
|
|
1446
|
-
}
|
|
1447
|
-
return null;
|
|
1448
|
-
}
|
|
1449
|
-
function getResourcesBinPath2() {
|
|
1450
|
-
const envBinPath = process.env.IDeviceBinPath;
|
|
1451
|
-
if (envBinPath) {
|
|
1452
|
-
return envBinPath;
|
|
1453
|
-
}
|
|
1454
|
-
const bundledPath = getBundledResourcesPath2();
|
|
1455
|
-
if (bundledPath) {
|
|
1456
|
-
return bundledPath;
|
|
1457
|
-
}
|
|
1458
|
-
if (process.platform === "darwin") {
|
|
1459
|
-
const homebrewArmPath = "/opt/homebrew/bin";
|
|
1460
|
-
if (existsSync2(join2(homebrewArmPath, "iproxy"))) {
|
|
1461
|
-
return homebrewArmPath;
|
|
1462
|
-
}
|
|
1463
|
-
const homebrewIntelPath = "/usr/local/bin";
|
|
1464
|
-
if (existsSync2(join2(homebrewIntelPath, "iproxy"))) {
|
|
1465
|
-
return homebrewIntelPath;
|
|
1466
|
-
}
|
|
1467
|
-
}
|
|
1468
|
-
if (process.platform === "linux") {
|
|
1469
|
-
const linuxPaths = ["/usr/bin", "/usr/local/bin"];
|
|
1470
|
-
for (const linuxPath of linuxPaths) {
|
|
1471
|
-
if (existsSync2(join2(linuxPath, "iproxy"))) {
|
|
1472
|
-
return linuxPath;
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
}
|
|
1476
|
-
return "";
|
|
1477
|
-
}
|
|
1436
|
+
import { join as join4 } from "node:path";
|
|
1478
1437
|
function startPortForward(localPort, devicePort, udid, startupTimeout = 500) {
|
|
1479
1438
|
return new Promise((resolve, reject) => {
|
|
1480
1439
|
logTask(`Starting port forward ${localPort} -> ${devicePort} for device ${udid}`);
|
|
1481
|
-
const binPath =
|
|
1440
|
+
const binPath = getResourcesBinPath();
|
|
1482
1441
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
1483
|
-
const toolPath = binPath ?
|
|
1442
|
+
const toolPath = binPath ? join4(binPath, `iproxy${ext}`) : `iproxy${ext}`;
|
|
1484
1443
|
const spawnOptions = {
|
|
1485
1444
|
windowsHide: true,
|
|
1486
1445
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -1488,6 +1447,9 @@ function startPortForward(localPort, devicePort, udid, startupTimeout = 500) {
|
|
|
1488
1447
|
if (binPath) {
|
|
1489
1448
|
spawnOptions.cwd = binPath;
|
|
1490
1449
|
}
|
|
1450
|
+
logInfo(`Spawning iproxy with path: ${toolPath}`);
|
|
1451
|
+
logInfo(`Arguments: ${[localPort.toString(), devicePort.toString(), "-u", udid].join(" ")}`);
|
|
1452
|
+
logInfo(`Options: ${JSON.stringify(spawnOptions)}`);
|
|
1491
1453
|
const child = spawn(
|
|
1492
1454
|
toolPath,
|
|
1493
1455
|
[localPort.toString(), devicePort.toString(), "-u", udid],
|
|
@@ -1495,7 +1457,11 @@ function startPortForward(localPort, devicePort, udid, startupTimeout = 500) {
|
|
|
1495
1457
|
);
|
|
1496
1458
|
let hasResolved = false;
|
|
1497
1459
|
let stderrOutput = "";
|
|
1460
|
+
child.stdout?.on("data", (data) => {
|
|
1461
|
+
logTask(`${data.toString()}`);
|
|
1462
|
+
});
|
|
1498
1463
|
child.stderr?.on("data", (data) => {
|
|
1464
|
+
logError(`${data.toString()}`);
|
|
1499
1465
|
const msg = data.toString();
|
|
1500
1466
|
stderrOutput += msg;
|
|
1501
1467
|
if (msg.toLowerCase().includes("error") && !hasResolved) {
|