From 7e15affb40d1763f1eaf79fe20dd3d77ee2c2089 Mon Sep 17 00:00:00 2001 From: Ayushman Chhabra <14110965+ayushmanchhabra@users.noreply.github.com> Date: Tue, 27 Jan 2026 13:12:28 +0530 Subject: [PATCH 1/3] Add type checking step to CI workflow --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 02f7265..c32c043 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,9 @@ jobs: - name: Check for type errors run: npm run type + - name: Check for typing errors + run: npm run type + - name: Run tests with coverage id: coverage shell: bash From ab6b164a60762e1003509591fdc1bf7a9a7c670d Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 17:50:21 +0530 Subject: [PATCH 2/3] Add TypeScript configuration and type definitions (#19) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds TypeScript compiler configuration and type definitions to support type checking in CI without modifying application source code. ## Changes - **tsconfig.json**: Added ES2020 target/lib, esModuleInterop, and allowSyntheticDefaultImports for proper module resolution - **Dependencies**: Installed `@types/node`, `@types/semver`, and `@types/yauzl-promise` for Node.js, semver, and yauzl-promise type support This PR focuses exclusively on TypeScript configuration and type declarations. Source code type errors will be addressed in a separate PR. --- 💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey). --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: ayushmanchhabra <14110965+ayushmanchhabra@users.noreply.github.com> --- package-lock.json | 37 +++++++++++++++++++++++++++++++++++++ package.json | 3 +++ tsconfig.json | 9 ++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 0593112..a50c52b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,9 @@ }, "devDependencies": { "@eslint/js": "^9.39.2", + "@types/node": "^25.0.10", + "@types/semver": "^7.7.1", + "@types/yauzl-promise": "^4.0.1", "eslint": "^9.39.2", "eslint-plugin-jsdoc": "^62.1.0", "globals": "^17.0.0", @@ -602,6 +605,33 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/node": { + "version": "25.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", + "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yauzl-promise": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/yauzl-promise/-/yauzl-promise-4.0.1.tgz", + "integrity": "sha512-qYEC3rJwqiJpdQ9b+bPNeuSY0c3JUM8vIuDy08qfuVN7xHm3ZDsHn2kGphUIB0ruEXrPGNXZ64nMUcu4fDjViQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/types": { "version": "8.53.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.53.0.tgz", @@ -1803,6 +1833,13 @@ "node": ">=14.17" } }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", diff --git a/package.json b/package.json index 2d0833f..3ec6d14 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,9 @@ }, "devDependencies": { "@eslint/js": "^9.39.2", + "@types/node": "^25.0.10", + "@types/semver": "^7.7.1", + "@types/yauzl-promise": "^4.0.1", "eslint": "^9.39.2", "eslint-plugin-jsdoc": "^62.1.0", "globals": "^17.0.0", diff --git a/tsconfig.json b/tsconfig.json index ab3f75f..82c8527 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,14 @@ "declaration": true, "emitDeclarationOnly": true, "outDir": "types", - "strict": true + "strict": true, + "target": "ES2020", + "lib": ["ES2020"], + "module": "ESNext", + "moduleResolution": "node", + "types": ["node"], + "esModuleInterop": true, + "allowSyntheticDefaultImports": true }, "include": [ "src/**/*.js" From b7f4cacef3549c014edce67216cd6f3a490f5358 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 27 Jan 2026 23:26:45 +0530 Subject: [PATCH 3/3] Fix TypeScript type errors in source files (#20) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TypeScript strict type checking was enabled but the codebase had 7 type errors preventing successful compilation. **Fixed type errors:** - **decompress.js**: Added explicit `Buffer[]` type annotation for chunks array to resolve implicit `any[]` inference - **ffmpeg.js, node.js**: Added missing return statements to match JSDoc `Promise` declarations - **main.js**: Added null check for `semver.coerce()` result and eliminated redundant coerce call - **request.js**: Added undefined check for `res.statusCode` before comparison **Example fix (main.js):** ```javascript // Before: called coerce twice, missing null check } else if (semver.valid(semver.coerce(options.version))) { options.version = semver.coerce(options.version).version; // After: single call with proper null handling } else { const coerced = semver.coerce(options.version); if (coerced && semver.valid(coerced)) { options.version = coerced.version; ``` All changes maintain existing runtime behavior while satisfying TypeScript's strict type checking requirements. --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: ayushmanchhabra <14110965+ayushmanchhabra@users.noreply.github.com> --- src/decompress.js | 1 + src/ffmpeg.js | 1 + src/main.js | 9 ++++++--- src/node.js | 1 + src/request.js | 2 +- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/decompress.js b/src/decompress.js index 1a95b8a..f18ced2 100644 --- a/src/decompress.js +++ b/src/decompress.js @@ -87,6 +87,7 @@ async function unzip(zippedFile, cacheDir) { for (const symlinkEntry of symlinks) { let entryPathAbs = path.join(cacheDir, symlinkEntry.filename); const readStream = await symlinkEntry.openReadStream(); + /** @type {Buffer[]} */ const chunks = []; readStream.on('data', (chunk) => chunks.push(chunk)); await new Promise(resolve => readStream.on('end', resolve)); diff --git a/src/ffmpeg.js b/src/ffmpeg.js index 300eacb..bfde934 100644 --- a/src/ffmpeg.js +++ b/src/ffmpeg.js @@ -35,4 +35,5 @@ export default async function ffmpeg(downloadUrl, version, platform, arch, cache ); await request(url, ffmpegFileAbs); + return ffmpegFileAbs; } diff --git a/src/main.js b/src/main.js index d269452..7662500 100644 --- a/src/main.js +++ b/src/main.js @@ -54,10 +54,13 @@ async function get(options) { || options.version === "lts" ) { options.version = manifestData[options.version].slice(1); - } else if (semver.valid(semver.coerce(options.version))) { - options.version = semver.coerce(options.version).version; } else { - throw new Error('Expected "options.version" to be "latest", "stable", "lts" or a valid semver version. Received: ' + options.version); + const coerced = semver.coerce(options.version); + if (coerced && semver.valid(coerced)) { + options.version = coerced.version; + } else { + throw new Error('Expected "options.version" to be "latest", "stable", "lts" or a valid semver version. Received: ' + options.version); + } } if (options.flavor !== "normal" && options.flavor !== "sdk") { diff --git a/src/node.js b/src/node.js index 24829ea..9343026 100644 --- a/src/node.js +++ b/src/node.js @@ -45,4 +45,5 @@ export default async function nw(downloadUrl, version, cacheDir) { ); await request(url, nwFileAbs); + return nwFileAbs; } diff --git a/src/request.js b/src/request.js index dbd9193..e9fe940 100644 --- a/src/request.js +++ b/src/request.js @@ -44,7 +44,7 @@ export default function request(url, filePath) { }, (res) => { /* Redirect handling */ - if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { + if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { cleanup(); const redirectedUrl = new URL(res.headers.location, parsedUrl).toString();