const assert = require("node:assert/strict"); const test = require("node:test"); const pkg = require("../package.json"); const { _internal } = require("../scripts/install"); test("postinstall opts into optional install mode", () => { assert.equal(pkg.scripts.postinstall, "node scripts/install.js --optional"); }); test("optional install can be enabled by command-line flag or env", () => { assert.equal(_internal.isOptionalInstall(["--optional"], {}), true); assert.equal(_internal.isOptionalInstall([], {}), false); assert.equal(_internal.isOptionalInstall([], { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), true); assert.equal(_internal.isOptionalInstall([], { DEEPSEEK_OPTIONAL_INSTALL: "1" }), true); }); test("optional mode only changes install-time defaults", () => { assert.equal(_internal.maxAttempts("install", { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), 1); assert.equal(_internal.maxAttempts("runtime", { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), 5); assert.equal(_internal.defaultTimeoutMs("install", { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), 15_000); assert.equal(_internal.defaultTimeoutMs("runtime", { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), 300_000); assert.equal(_internal.defaultStallMs("install", { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), 5_000); assert.equal(_internal.defaultStallMs("runtime", { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), 30_000); }); test("pnpm optional postinstall skips install-time download", () => { assert.equal( _internal.shouldSkipOptionalPostinstall("install", ["--optional"], { npm_config_user_agent: "pnpm/10.11.0 npm/? node/v22.15.0 win32 x64", }), true, ); assert.equal( _internal.shouldSkipOptionalPostinstall("runtime", ["--optional"], { npm_config_user_agent: "pnpm/10.11.0 npm/? node/v22.15.0 win32 x64", }), false, ); assert.equal( _internal.shouldSkipOptionalPostinstall("install", [], { npm_config_user_agent: "pnpm/10.11.0 npm/? node/v22.15.0 win32 x64", }), false, ); assert.equal( _internal.shouldSkipOptionalPostinstall("install", ["--optional"], { npm_config_user_agent: "npm/11.3.0 node/v22.15.0 win32 x64", }), false, ); }); test("optional install only swallows retryable download failures", () => { const socketHangUp = new Error("socket hang up"); assert.equal( _internal.shouldIgnoreInstallFailure("install", socketHangUp, ["--optional"], {}), true, ); const timedOut = new Error("download exceeded total timeout of 15000 ms"); timedOut.code = "EDOWNLOADTIMEOUT"; assert.equal( _internal.shouldIgnoreInstallFailure("install", timedOut, ["--optional"], {}), true, ); const unsupported = new Error("Unsupported platform: freebsd"); assert.equal( _internal.shouldIgnoreInstallFailure("install", unsupported, ["--optional"], {}), false, ); const badChecksum = new Error("Checksum mismatch for codewhale-linux-x64"); badChecksum.nonRetryable = true; assert.equal( _internal.shouldIgnoreInstallFailure("install", badChecksum, ["--optional"], {}), false, ); const glibc = new Error("requires glibc 2.34 or newer"); glibc.nonRetryable = true; assert.equal( _internal.shouldIgnoreInstallFailure("install", glibc, ["--optional"], {}), false, ); }); test("optional install still swallows wrapped http 5xx failures", async () => { const previous = process.env.DEEPSEEK_TUI_OPTIONAL_INSTALL; process.env.DEEPSEEK_TUI_OPTIONAL_INSTALL = "1"; const http5xx = new Error("Request failed with status 502: https://example.invalid"); http5xx.name = "HttpStatusError"; http5xx.status = 502; try { await assert.rejects( _internal.withRetry("fetch https://example.invalid", async () => { throw http5xx; }, "install"), (wrapped) => { assert.equal(wrapped.name, "HttpStatusError"); assert.equal(wrapped.status, 502); assert.equal( _internal.shouldIgnoreInstallFailure("install", wrapped, ["--optional"], {}), true, ); return true; }, ); } finally { if (previous === undefined) { delete process.env.DEEPSEEK_TUI_OPTIONAL_INSTALL; } else { process.env.DEEPSEEK_TUI_OPTIONAL_INSTALL = previous; } } }); test("withRetry prints install hint on first retryable failure", async () => { const previousWrite = process.stderr.write; const previousSetTimeout = global.setTimeout; let stderr = ""; let attempts = 0; process.stderr.write = (chunk) => { stderr += String(chunk); return true; }; global.setTimeout = (callback) => { callback(); return 0; }; try { const result = await _internal.withRetry( "fetch https://github.com/example", async () => { attempts += 1; if (attempts === 1) { const err = new Error("connect ETIMEDOUT 20.205.243.166:443"); err.code = "ETIMEDOUT"; throw err; } return "ok"; }, "runtime", ); assert.equal(result, "ok"); assert.equal(attempts, 2); assert.match(stderr, /codewhale install hint:/); assert.match(stderr, /#npm-binary-download-times-out/); } finally { process.stderr.write = previousWrite; global.setTimeout = previousSetTimeout; } });