@pushpalsdev/cli 1.0.98 → 1.0.99
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/package.json
CHANGED
|
@@ -53,6 +53,12 @@ function ensureSandboxGitConfig(homeDir: string): void {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
function withNodeDnsIpv4First(value: string | undefined): string {
|
|
57
|
+
const existing = (value ?? "").trim();
|
|
58
|
+
if (/(^|\s)--dns-result-order=/.test(existing)) return existing;
|
|
59
|
+
return [existing, "--dns-result-order=ipv4first"].filter(Boolean).join(" ");
|
|
60
|
+
}
|
|
61
|
+
|
|
56
62
|
function resolveOriginalHome(env: Record<string, string>): string {
|
|
57
63
|
return env.HOME || env.USERPROFILE || homedir();
|
|
58
64
|
}
|
|
@@ -100,6 +106,8 @@ export function buildWorkerSandboxWritableEnv(
|
|
|
100
106
|
EXPO_NO_INTERACTIVE: env.EXPO_NO_INTERACTIVE ?? "1",
|
|
101
107
|
CI: env.CI ?? "1",
|
|
102
108
|
BROWSER: env.BROWSER ?? "none",
|
|
109
|
+
NODE_OPTIONS: withNodeDnsIpv4First(env.NODE_OPTIONS),
|
|
110
|
+
REACT_NATIVE_PACKAGER_HOSTNAME: env.REACT_NATIVE_PACKAGER_HOSTNAME ?? "127.0.0.1",
|
|
103
111
|
EXPO_DEV_SERVER_PORT: env.EXPO_DEV_SERVER_PORT ?? defaultExpoPort,
|
|
104
112
|
RCT_METRO_PORT: env.RCT_METRO_PORT ?? defaultExpoPort,
|
|
105
113
|
PUSHPALS_VALIDATION_REPO: repo,
|
|
@@ -647,7 +647,49 @@ async function terminateValidationProcessTree(
|
|
|
647
647
|
}
|
|
648
648
|
}
|
|
649
649
|
|
|
650
|
-
|
|
650
|
+
function captureValidationStream(stream: ReadableStream<Uint8Array> | null) {
|
|
651
|
+
let text = "";
|
|
652
|
+
let done = false;
|
|
653
|
+
const reader = stream?.getReader();
|
|
654
|
+
const promise = reader
|
|
655
|
+
? (async () => {
|
|
656
|
+
try {
|
|
657
|
+
while (true) {
|
|
658
|
+
const result = await reader.read();
|
|
659
|
+
if (result.done) break;
|
|
660
|
+
text += Buffer.from(result.value).toString("utf8");
|
|
661
|
+
}
|
|
662
|
+
} catch {
|
|
663
|
+
// Stream cancellation after process exit is expected when descendants
|
|
664
|
+
// inherit pipes from failed browser/dev-server launchers.
|
|
665
|
+
} finally {
|
|
666
|
+
done = true;
|
|
667
|
+
try {
|
|
668
|
+
reader.releaseLock();
|
|
669
|
+
} catch {
|
|
670
|
+
// ignore
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
})()
|
|
674
|
+
: Promise.resolve().then(() => {
|
|
675
|
+
done = true;
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
return {
|
|
679
|
+
cancel: async () => {
|
|
680
|
+
try {
|
|
681
|
+
await reader?.cancel();
|
|
682
|
+
} catch {
|
|
683
|
+
// ignore
|
|
684
|
+
}
|
|
685
|
+
},
|
|
686
|
+
isDone: () => done,
|
|
687
|
+
promise,
|
|
688
|
+
text: () => text,
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
export async function runValidationArgv(
|
|
651
693
|
repo: string,
|
|
652
694
|
command: string,
|
|
653
695
|
argv: string[],
|
|
@@ -665,31 +707,52 @@ async function runValidationArgv(
|
|
|
665
707
|
stderr: "pipe",
|
|
666
708
|
detached: process.platform !== "win32",
|
|
667
709
|
});
|
|
710
|
+
const stdoutCapture = captureValidationStream(proc.stdout);
|
|
711
|
+
const stderrCapture = captureValidationStream(proc.stderr);
|
|
668
712
|
let timedOut = false;
|
|
669
|
-
const
|
|
670
|
-
|
|
713
|
+
const timeout = Math.max(1_000, timeoutMs);
|
|
714
|
+
let timeoutTimer: ReturnType<typeof setTimeout> | null = null;
|
|
715
|
+
const timeoutPromise = new Promise<"timeout">((resolveTimeout) => {
|
|
716
|
+
timeoutTimer = setTimeout(() => {
|
|
671
717
|
timedOut = true;
|
|
672
718
|
void terminateValidationProcessTree(proc);
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
);
|
|
719
|
+
resolveTimeout("timeout");
|
|
720
|
+
}, timeout);
|
|
721
|
+
});
|
|
722
|
+
const exitOrTimeout = await Promise.race([
|
|
723
|
+
proc.exited.then((code) => ({ type: "exit" as const, code })),
|
|
724
|
+
timeoutPromise,
|
|
725
|
+
]);
|
|
726
|
+
if (timeoutTimer) clearTimeout(timeoutTimer);
|
|
727
|
+
const exitCode = exitOrTimeout === "timeout" ? 124 : exitOrTimeout.code;
|
|
728
|
+
|
|
729
|
+
if (!timedOut) {
|
|
730
|
+
await Promise.race([
|
|
731
|
+
Promise.all([stdoutCapture.promise, stderrCapture.promise]),
|
|
732
|
+
Bun.sleep(1_000),
|
|
733
|
+
]);
|
|
734
|
+
if (!stdoutCapture.isDone() || !stderrCapture.isDone()) {
|
|
735
|
+
await terminateValidationProcessTree(proc);
|
|
736
|
+
await Promise.all([stdoutCapture.cancel(), stderrCapture.cancel()]);
|
|
737
|
+
}
|
|
738
|
+
} else {
|
|
739
|
+
await Promise.all([stdoutCapture.cancel(), stderrCapture.cancel()]);
|
|
740
|
+
}
|
|
676
741
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
proc.exited,
|
|
742
|
+
await Promise.race([
|
|
743
|
+
Promise.all([stdoutCapture.promise, stderrCapture.promise]),
|
|
744
|
+
Bun.sleep(500),
|
|
681
745
|
]);
|
|
682
|
-
clearTimeout(timer);
|
|
683
746
|
|
|
684
747
|
return {
|
|
685
748
|
step: command,
|
|
686
749
|
command,
|
|
687
750
|
ok: !timedOut && exitCode === 0,
|
|
688
|
-
exitCode
|
|
689
|
-
stdout: compactJobOutput(
|
|
751
|
+
exitCode,
|
|
752
|
+
stdout: compactJobOutput(stdoutCapture.text().trim(), outputPolicy),
|
|
690
753
|
stderr: compactJobOutput(
|
|
691
754
|
[
|
|
692
|
-
|
|
755
|
+
stderrCapture.text().trim(),
|
|
693
756
|
timedOut ? timeoutMessage : "",
|
|
694
757
|
]
|
|
695
758
|
.filter(Boolean)
|
|
@@ -1242,6 +1305,10 @@ function detectValidationBlocker(runs: ValidationExecutionResult[]): ValidationB
|
|
|
1242
1305
|
combined.includes("network access") ||
|
|
1243
1306
|
combined.includes("connection refused") ||
|
|
1244
1307
|
combined.includes("getaddrinfo") ||
|
|
1308
|
+
combined.includes("err_socket_bad_port") ||
|
|
1309
|
+
combined.includes("expo exited early") ||
|
|
1310
|
+
combined.includes("eperm") ||
|
|
1311
|
+
combined.includes("operation not permitted") ||
|
|
1245
1312
|
combined.includes("eacces")
|
|
1246
1313
|
) {
|
|
1247
1314
|
return {
|