Merge pull request #1 from warkanum/claude/dazzling-gauss-hgwaii

Fix workspace peer-dep, strict-mode, and workspace-range bugs
This commit is contained in:
Hein Puth (Warkanum) authored and GitHub committed 2026-09-24 09:29:50 +02:00
commit c593038155
3 files changed
+26 -71

No files matched your search

+4 -1
View File
@@ -12,4 +12,7 @@ const require = createRequire(import.meta.url);
// Convert the file path to a proper file:// URL
const modulePath = pathToFileURL(join(__dirname, '../dist/index.js')).href;
const { default: run } = await import(modulePath);
run().catch(console.error);
run().catch((error) => {
console.error(error);
process.exit(1);
});
+2 -1
View File
@@ -1,5 +1,6 @@
import fs from 'fs';
import path from 'path';
import { pathToFileURL } from 'url';
import chalk from 'chalk';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
@@ -157,7 +158,7 @@ const cli = async () => {
// Export both the CLI function and run it if this is the main module
export { cli as default };
if (process.argv[1] === import.meta.url.slice(7)) {
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
cli().catch(error => {
console.error(chalk.red('Unexpected error:'));
console.error(error);
+20 -69
View File
@@ -188,7 +188,8 @@ class DependencyChecker {
if (version.startsWith("workspace:")) {
const workspaceVersion = version.replace("workspace:", "");
if (workspaceVersion === "*") return null;
if (semver.valid(workspaceVersion)) return workspaceVersion;
const cleanWorkspaceVersion = workspaceVersion.replace(/^[~^<>=]+\s*/g, "");
if (semver.valid(cleanWorkspaceVersion)) return cleanWorkspaceVersion;
return null;
}
@@ -241,9 +242,8 @@ class DependencyChecker {
Object.entries(packageDeps).forEach(([dep, version]) => {
if (
(!appDeps[dep] &&
this.shouldIncludeDependency(dep, version, packageJson)) ||
(packageJson.peerDependencies?.[dep] && !appDeps[dep])
!appDeps[dep] &&
this.shouldIncludeDependency(dep, version, packageJson)
) {
missing.push({ name: dep, version });
uniqueMissingDeps.add(dep);
@@ -608,19 +608,22 @@ class DependencyChecker {
if (appDependencies[dep]) {
const appVersion = appDependencies[dep];
// In strict mode, check if versions are compatible within range constraints
if (this.strictMode && this.hasVersionRange(version)) {
if (!this.isVersionCompatible(version, appVersion)) {
// Only update if the app version doesn't satisfy the range
if (this.strictMode) {
// Strict mode: only touch dependencies with a version range,
// and only when the app version falls outside that range.
if (
this.hasVersionRange(version) &&
!this.isVersionCompatible(version, appVersion)
) {
const cleanAppVersion = appVersion.replace(/^[~^<>=]+\s*/g, "");
const versionPrefix = version.match(/^[~^<>=]+\s*/)?.[0] || '';
const newVersion = versionPrefix + cleanAppVersion;
if (!dryRun) {
packageJson[section]![dep] = newVersion;
}
updates.push({
package: packageJson.name,
dependency: dep,
@@ -628,22 +631,22 @@ class DependencyChecker {
to: newVersion,
type: section,
});
hasUpdates = true;
}
} else {
// Original behavior for non-strict mode
// Non-strict mode: always align to the app's version.
const cleanCurrentVersion = version.replace(/^[~^<>=]+\s*/g, "");
const cleanAppVersion = appVersion.replace(/^[~^<>=]+\s*/g, "");
if (cleanCurrentVersion !== cleanAppVersion) {
const versionPrefix = version.match(/^[~^<>=]+\s*/)?.[0] || '';
const newVersion = versionPrefix + cleanAppVersion;
if (!dryRun) {
packageJson[section]![dep] = newVersion;
}
updates.push({
package: packageJson.name,
dependency: dep,
@@ -651,7 +654,7 @@ class DependencyChecker {
to: newVersion,
type: section,
});
hasUpdates = true;
}
}
@@ -746,59 +749,7 @@ class DependencyChecker {
return;
}
if (format === "text") {
this.displayVersionDifferences();
return;
}
const output = {
summary: {
conflicts: Array.from(this.dependencyMap.entries())
.filter(([, depInfo]) => depInfo.versions.size > 1)
.map(([dep, depInfo]) => ({
name: dep,
versions: Array.from(depInfo.versions.entries()).map(
([version, info]) => ({
version,
packages: Array.from(info.packages),
paths: Array.from(info.packages).map((pkg) => {
const filePath = this.packageJsonFiles.find((file) => {
const json = JSON.parse(
fs.readFileSync(file, "utf8")
) as PackageJson;
return json.name === pkg;
});
return {
package: pkg,
path: path.relative(process.cwd(), filePath || ""),
};
}),
usages: Array.from(info.usages),
})
),
})),
},
fullAnalysis: Object.fromEntries(
Array.from(this.dependencyMap.entries()).map(([dep, depInfo]) => [
dep,
{
versions: Object.fromEntries(
Array.from(depInfo.versions.entries()).map(([version, info]) => [
version,
{
packages: Array.from(info.packages),
usages: Array.from(info.usages),
},
])
),
usedAsNormal: depInfo.usedAsNormal,
usedAsPeer: depInfo.usedAsPeer,
},
])
),
};
console.log(JSON.stringify(output, null, 2));
this.displayVersionDifferences();
}
public async run(options: RunOptions = {}): Promise<void> {