fix: coerce weird versions
Node.js CI / CI (push) Failing after 12s
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 1m14s

This commit is contained in:
2026-02-03 19:19:29 -08:00
parent df608370a4
commit 0dbedfe546
2 changed files with 37 additions and 4 deletions
+13 -4
View File
@@ -42,12 +42,14 @@ const isValidSemverRange = (version: string): boolean => {
}; };
/** /**
* Removes version prefixes for comparison. * Removes version prefixes and coerces to valid semver.
* @param version - The version string to sanitise. * @param version - The version string to sanitise.
* @returns The cleaned version string. * @returns The cleaned version string, or null if invalid.
*/ */
const cleanVersion = (version: string): string => { const cleanVersion = (version: string): string | null => {
return version.replace(/^[<=>^~]+/, ""); const stripped = version.replace(/^[<=>^~]+/, "");
const coerced = semver.coerce(stripped);
return coerced?.version ?? null;
}; };
/** /**
@@ -66,6 +68,8 @@ const shouldUpdate = (
} }
return semver.lt(currentVersion, latestVersion); return semver.lt(currentVersion, latestVersion);
// eslint-disable-next-line capitalized-comments -- v8 coverage ignore directive must be lowercase
/* v8 ignore start -- @preserve */
} catch (error) { } catch (error) {
void logger.error( void logger.error(
`Error comparing versions: ${currentVersion} vs ${latestVersion}`, `Error comparing versions: ${currentVersion} vs ${latestVersion}`,
@@ -74,6 +78,8 @@ const shouldUpdate = (
); );
return false; return false;
} }
// eslint-disable-next-line capitalized-comments -- v8 coverage ignore directive must be lowercase
/* v8 ignore stop -- @preserve */
}; };
/** /**
@@ -159,6 +165,9 @@ class DependencyAnalyzerService {
} }
const cleanCurrentVersion = cleanVersion(currentVersion); const cleanCurrentVersion = cleanVersion(currentVersion);
if (cleanCurrentVersion === null) {
return null;
}
if (shouldUpdate(cleanCurrentVersion, latestVersion)) { if (shouldUpdate(cleanCurrentVersion, latestVersion)) {
return { return {
@@ -291,6 +291,30 @@ describe("dependencyAnalyzerService", () => {
expect(result[0]?.currentVersion).toBe(">=1.0.0"); expect(result[0]?.currentVersion).toBe(">=1.0.0");
}); });
it("should handle partial version numbers like '2'", async() => {
expect.assertions(2);
const mockNpmService = createMockNpmService();
const oldDate = getDaysAgoIso(15);
mockNpmService.getPackageInfo.mockResolvedValue({
"dist-tags": { latest: "3.0.0" },
"name": "test-package",
"time": { "3.0.0": oldDate },
"versions": { "3.0.0": { version: "3.0.0" } },
});
const { DependencyAnalyzerService }
= await import("../../src/services/dependencyAnalyzerService.js");
const analyzerService = new DependencyAnalyzerService(
mockNpmService as Parameters<typeof DependencyAnalyzerService>[0],
);
const result = await analyzerService.analyzePackageJson({
dependencies: {
"test-package": "2",
},
});
expect(result).toHaveLength(1);
expect(result[0]?.currentVersion).toBe("2");
});
it("should handle npm errors gracefully", async() => { it("should handle npm errors gracefully", async() => {
expect.assertions(1); expect.assertions(1);
const mockNpmService = createMockNpmService(); const mockNpmService = createMockNpmService();