Last active
September 9, 2025 10:01
-
-
Save yunusemredilber/9d12653903dd79ee479618805205acc0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const { execSync } = require("child_process"); | |
| const fs = require("fs"); | |
| const packagesToCheck = [ | |
| "backslash", | |
| "chalk", | |
| "chalk-template", | |
| "color-convert", | |
| "color-name", | |
| "color-string", | |
| "wrap-ansi", | |
| "supports-hyperlinks", | |
| "strip-ansi", | |
| "slice-ansi", | |
| "simple-swizzle", | |
| "is-arrayish", | |
| "error-ex", | |
| "has-ansi", | |
| "ansi-regex", | |
| "ansi-styles", | |
| "supports-color", | |
| "proto-tinker-wc", | |
| "debug", | |
| ]; | |
| // Flagged versions | |
| const warnVersions = { | |
| "backslash": ["0.2.1"], | |
| "chalk": ["5.6.1"], | |
| "chalk-template": ["1.1.1"], | |
| "color-convert": ["3.1.1"], | |
| "color-name": ["2.0.1"], | |
| "color-string": ["2.1.1"], | |
| "wrap-ansi": ["9.0.1"], | |
| "supports-hyperlinks": ["4.1.1"], | |
| "strip-ansi": ["7.1.1"], | |
| "slice-ansi": ["7.1.1"], | |
| "simple-swizzle": ["0.2.3"], | |
| "is-arrayish": ["0.3.3"], | |
| "error-ex": ["1.3.3"], | |
| "has-ansi": ["6.0.1"], | |
| "ansi-regex": ["6.2.1"], | |
| "ansi-styles": ["6.2.2"], | |
| "supports-color": ["10.2.1"], | |
| "proto-tinker-wc": ["1.8.7"], | |
| "debug": ["4.4.2"], | |
| }; | |
| // Detect package manager | |
| let manager; | |
| if (fs.existsSync("pnpm-lock.yaml")) { | |
| manager = "pnpm"; | |
| } else if (fs.existsSync("yarn.lock")) { | |
| manager = "yarn"; | |
| } else { | |
| manager = "npm"; | |
| } | |
| console.log(`Detected package manager: ${manager}`); | |
| // Collect installed versions | |
| let versions = {}; | |
| try { | |
| if (manager === "npm") { | |
| const output = execSync("npm ls --all --json", { stdio: ["pipe", "pipe", "ignore"] }).toString(); | |
| const data = JSON.parse(output); | |
| function collectNpm(tree) { | |
| const deps = tree.dependencies || {}; | |
| for (const [name, dep] of Object.entries(deps)) { | |
| if (dep.version) { | |
| if (!versions[name]) versions[name] = new Set(); | |
| versions[name].add(dep.version); | |
| } | |
| collectNpm(dep); | |
| } | |
| } | |
| collectNpm(data); | |
| } else if (manager === "yarn") { | |
| const output = execSync("yarn list --json --no-progress --pattern ''", { stdio: ["pipe", "pipe"] }).toString(); | |
| const lines = output.split("\n").filter(Boolean); | |
| function walkYarnTrees(trees) { | |
| for (const t of trees) { | |
| if (t.name) { | |
| const match = t.name.match(/^([^@]+)@.*:(.+)$/); | |
| if (match) { | |
| const name = match[1]; | |
| const version = match[2]; | |
| if (!versions[name]) versions[name] = new Set(); | |
| versions[name].add(version); | |
| } | |
| } | |
| if (t.children) walkYarnTrees(t.children); | |
| } | |
| } | |
| for (const line of lines) { | |
| let obj; | |
| try { obj = JSON.parse(line); } catch { continue; } | |
| if (obj.type === "tree" && obj.data?.trees) { | |
| walkYarnTrees(obj.data.trees); | |
| } | |
| } | |
| } else if (manager === "pnpm") { | |
| const output = execSync(`pnpm list --parseable --long --depth Infinity | grep -E '${packagesToCheck.join("|")}'`, { stdio: ["pipe", "pipe"] }).toString(); | |
| const lines = output.split("\n").filter(Boolean); | |
| for (const line of lines) { | |
| const last = line.split("/").pop(); // get last segment | |
| const match = last.match(/^(@?[^@]+)@(.+)$/); | |
| if (match) { | |
| const name = match[1].split(":")[1]; | |
| const version = match[2]; | |
| if (!versions[name]) versions[name] = new Set(); | |
| versions[name].add(version); | |
| } | |
| } | |
| } | |
| } catch (err) { | |
| console.error("Error collecting versions:", err.message); | |
| process.exit(1); | |
| } | |
| // Print results with warnings | |
| let hasWarnings = false; | |
| packagesToCheck.forEach((pkg) => { | |
| if (versions[pkg]) { | |
| const installed = Array.from(versions[pkg]); | |
| const warnings = installed.filter(v => warnVersions[pkg]?.includes(v)); | |
| if (warnings.length > 0) { | |
| console.log(`${pkg}: ${installed.join(", ")} ⚠️ WARNING: flagged version(s): ${warnings.join(", ")}`); | |
| hasWarnings = true; | |
| } else { | |
| console.log(`${pkg}: ${installed.join(", ")}`); | |
| } | |
| } else { | |
| console.log(`${pkg}: (not installed)`); | |
| } | |
| }); | |
| if (hasWarnings) process.exit(1); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment