From 02a4d2d69f7dd22749016d66978cd63c9c5958d1 Mon Sep 17 00:00:00 2001 From: fraxken Date: Fri, 9 May 2025 18:05:58 +0200 Subject: [PATCH] feat(mama): implement hasZeroSemver getter --- workspaces/mama/README.md | 3 ++ workspaces/mama/src/ManifestManager.class.ts | 9 +++++ workspaces/mama/test/ManifestManager.spec.ts | 40 ++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/workspaces/mama/README.md b/workspaces/mama/README.md index 32f0ac0a..db03b146 100644 --- a/workspaces/mama/README.md +++ b/workspaces/mama/README.md @@ -119,6 +119,9 @@ Return true if `workspaces` property is present > [!NOTE] > Workspace are described by the interface `WorkspacesPackageJSON` (from @nodesecure/npm-types) +### hasZeroSemver +Return true if `version` is starting with `0.x` + ### flags Since we've created this package for security purposes, the instance contains various flags indicating threats detected in the content: diff --git a/workspaces/mama/src/ManifestManager.class.ts b/workspaces/mama/src/ManifestManager.class.ts index d96860c1..04cd7eb7 100644 --- a/workspaces/mama/src/ManifestManager.class.ts +++ b/workspaces/mama/src/ManifestManager.class.ts @@ -88,6 +88,15 @@ export class ManifestManager< .some((script) => kUnsafeNPMScripts.has(script.toLowerCase())); } + get hasZeroSemver() { + if (typeof this.document.version === "string") { + return /^0(\.\d+)*$/ + .test(this.document.version); + } + + return false; + } + get nodejsImports() { return this.document.imports ?? {}; } diff --git a/workspaces/mama/test/ManifestManager.spec.ts b/workspaces/mama/test/ManifestManager.spec.ts index 22f9fcf7..f0010810 100644 --- a/workspaces/mama/test/ManifestManager.spec.ts +++ b/workspaces/mama/test/ManifestManager.spec.ts @@ -435,6 +435,46 @@ describe("ManifestManager", () => { }); }); + describe("get hasZeroSemver", () => { + test("Given a PackageJSON with a semver higher than 1.x.x then it must return false", () => { + const packageJSON: PackageJSON = { + ...kMinimalPackageJSON + }; + + const mama = new ManifestManager(packageJSON); + assert.strictEqual(mama.hasZeroSemver, false); + }); + + test("Given a PackageJSON with a semver starting with 0.x it must return true", () => { + const packageJSON: PackageJSON = { + name: "foobar", + version: "0.5.5" + }; + + const mama = new ManifestManager(packageJSON); + assert.ok(mama.hasZeroSemver); + }); + + test("Given a WorkspacesPackageJSON with no version it must return false", () => { + const packageJSON: WorkspacesPackageJSON = { + workspaces: [] + }; + + const mama = new ManifestManager(packageJSON); + assert.strictEqual(mama.hasZeroSemver, false); + }); + + test("Given a WorkspacesPackageJSON with a semver starting with 0.x it must return true", () => { + const packageJSON: WorkspacesPackageJSON = { + version: "0.1.2", + workspaces: [] + }; + + const mama = new ManifestManager(packageJSON); + assert.ok(mama.hasZeroSemver); + }); + }); + describe("get license", () => { test("Given a minimal PackageJSON with no license field then it must return null", () => { const mama = new ManifestManager(kMinimalPackageJSON);