diff --git a/.changeset/ripe-wombats-fly.md b/.changeset/ripe-wombats-fly.md new file mode 100644 index 00000000..248fb577 --- /dev/null +++ b/.changeset/ripe-wombats-fly.md @@ -0,0 +1,5 @@ +--- +"@nodesecure/scanner": patch +--- + +remove faulty manifestAuthor helper for utils.parseAuthor diff --git a/workspaces/scanner/src/depWalker.ts b/workspaces/scanner/src/depWalker.ts index 0632e0ac..3eb8f6d5 100644 --- a/workspaces/scanner/src/depWalker.ts +++ b/workspaces/scanner/src/depWalker.ts @@ -9,6 +9,7 @@ import { Mutex, MutexRelease } from "@openally/mutex"; import { scanDirOrArchive, type scanDirOrArchiveOptions } from "@nodesecure/tarball"; import * as Vulnera from "@nodesecure/vulnera"; import { npm } from "@nodesecure/tree-walker"; +import { parseAuthor } from "@nodesecure/utils"; import type { ManifestVersion, PackageJSON } from "@nodesecure/npm-types"; // Import Internal Dependencies @@ -16,7 +17,6 @@ import { getDependenciesWarnings, addMissingVersionFlags, getUsedDeps, - manifestAuthor, getManifestLinks } from "./utils/index.js"; import { packageMetadata, manifestMetadata } from "./npmRegistry.js"; @@ -240,12 +240,12 @@ export async function depWalker( if (isLocalManifest(verDescriptor, manifest, packageName)) { Object.assign(dependency.metadata, { - author: manifestAuthor(manifest.author), + author: parseAuthor(manifest.author), homepage: manifest.homepage }); Object.assign(verDescriptor, { - author: manifestAuthor(manifest.author), + author: parseAuthor(manifest.author), links: getManifestLinks(manifest), repository: manifest.repository }); diff --git a/workspaces/scanner/src/utils/index.ts b/workspaces/scanner/src/utils/index.ts index 3ad7acbc..2710abbb 100644 --- a/workspaces/scanner/src/utils/index.ts +++ b/workspaces/scanner/src/utils/index.ts @@ -4,7 +4,6 @@ export * from "./addMissingVersionFlags.js"; export * from "./getLinks.js"; export * from "./urlToString.js"; export * from "./getUsedDeps.js"; -export * from "./manifestAuthor.js"; export * from "./isNodesecurePayload.js"; export const NPM_TOKEN = typeof process.env.NODE_SECURE_TOKEN === "string" ? diff --git a/workspaces/scanner/src/utils/manifestAuthor.ts b/workspaces/scanner/src/utils/manifestAuthor.ts deleted file mode 100644 index 7d45effb..00000000 --- a/workspaces/scanner/src/utils/manifestAuthor.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Import Third-party Dependencies -import type { Contact } from "@nodesecure/npm-types"; - -export function manifestAuthor(author: string | Contact | undefined): Contact | null { - if (author === void 0) { - return null; - } - - if (typeof author === "string") { - if (author.trim() === "") { - return null; - } - - const authorRegexp = /^([^<(]+?)?[ \t]*(?:<([^>(]+?)>)?[ \t]*(?:\(([^)]+?)\)|$)/g; - const [_, name, email, url] = authorRegexp.exec(author) ?? []; - - return { name, email, url }; - } - - return author; -} diff --git a/workspaces/scanner/test/depWalker.spec.ts b/workspaces/scanner/test/depWalker.spec.ts index a142afeb..77840b57 100644 --- a/workspaces/scanner/test/depWalker.spec.ts +++ b/workspaces/scanner/test/depWalker.spec.ts @@ -2,7 +2,7 @@ import path from "node:path"; import url from "node:url"; import { readFileSync } from "node:fs"; -import { test } from "node:test"; +import { test, describe } from "node:test"; import assert from "node:assert"; // Import Third-party Dependencies @@ -196,31 +196,39 @@ test("highlight contacts from a remote package", async() => { ); }); -test("should parse author, homepage and links for non-npm package", async() => { - const result = await cwd(path.join(kFixturePath, "non-npm-package")); - - const dep = result.dependencies["non-npm-package"]; - const v1 = dep.versions["1.0.0"]; - - assert.deepEqual(v1.author, { - email: void 0, - name: "NodeSecure", - url: void 0 - }); - assert.deepStrictEqual(v1.links, { - npm: null, - homepage: "https://nodesecure.com", - repository: "https://github.com/NodeSecure/non-npm-package" - }); - assert.deepStrictEqual(v1.repository, { - type: "git", - url: "https://github.com/NodeSecure/non-npm-package.git" +describe("scanner.cwd()", () => { + test("should parse author, homepage and links for a local package who doesn't exist on the remote registry", async() => { + const result = await cwd(path.join(kFixturePath, "non-npm-package")); + + const dep = result.dependencies["non-npm-package"]; + const v1 = dep.versions["1.0.0"]; + + assert.deepEqual(v1.author, { + name: "NodeSecure" + }); + assert.deepStrictEqual(v1.links, { + npm: null, + homepage: "https://nodesecure.com", + repository: "https://github.com/NodeSecure/non-npm-package" + }); + assert.deepStrictEqual(v1.repository, { + type: "git", + url: "https://github.com/NodeSecure/non-npm-package.git" + }); + + assert.deepStrictEqual(dep.metadata.author, { + name: "NodeSecure" + }); + assert.strictEqual(dep.metadata.homepage, "https://nodesecure.com"); }); - assert.deepStrictEqual(dep.metadata.author, { - email: void 0, - name: "NodeSecure", - url: void 0 + test("should parse local manifest author field without throwing when attempting to highlight contacts", async() => { + const { dependencies } = await cwd( + path.join(kFixturePath, "non-valid-authors") + ); + const pkg = dependencies["random-package"]; + + assert.strictEqual(pkg.metadata.author, null); }); - assert.strictEqual(dep.metadata.homepage, "https://nodesecure.com"); }); + diff --git a/workspaces/scanner/test/fixtures/depWalker/non-valid-authors/package.json b/workspaces/scanner/test/fixtures/depWalker/non-valid-authors/package.json new file mode 100644 index 00000000..38610a3e --- /dev/null +++ b/workspaces/scanner/test/fixtures/depWalker/non-valid-authors/package.json @@ -0,0 +1,5 @@ +{ + "name": "random-package", + "type": "module", + "author": "John Doe , Alicia B " +} diff --git a/workspaces/scanner/test/utils/manifestAuthor.spec.ts b/workspaces/scanner/test/utils/manifestAuthor.spec.ts deleted file mode 100644 index cf4060e7..00000000 --- a/workspaces/scanner/test/utils/manifestAuthor.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -// Import Node.js Dependencies -import assert from "node:assert/strict"; -import { describe, it } from "node:test"; - -// Import Internal Dependencies -import * as utils from "../../src/utils/index.js"; - -describe("utils.manifestAuthor", () => { - it("should return null when given undefined", () => { - assert.strictEqual(utils.manifestAuthor(undefined), null); - }); - - it("should return null when given empty string", () => { - assert.strictEqual(utils.manifestAuthor(""), null); - }); - - it("should return author object with only name", () => { - assert.deepStrictEqual(utils.manifestAuthor("John Doe"), { - name: "John Doe", - email: void 0, - url: void 0 - }); - }); - - it("should return author object with name and email", () => { - assert.deepStrictEqual(utils.manifestAuthor("John Doe "), { - name: "John Doe", - email: "john@doe.com", - url: void 0 - }); - }); - - it("should return author object with name, email and url", () => { - assert.deepStrictEqual(utils.manifestAuthor("John Doe (john.com)"), { - name: "John Doe", - email: "john@doe.com", - url: "john.com" - }); - }); - - it("should return given author object", () => { - const author = { - name: "John Doe", - email: "john@doe.com", - url: "john.com" - }; - - assert.deepStrictEqual(utils.manifestAuthor(author), author); - }); -});