From 149af8680bace70ba6f59187daceb2321fa89b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 21 Apr 2026 17:32:32 +0300 Subject: [PATCH 1/3] test: add pinpoint npm fixture --- src/fixtures/pinpoint-npm-info.json | 35 +++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/fixtures/pinpoint-npm-info.json diff --git a/src/fixtures/pinpoint-npm-info.json b/src/fixtures/pinpoint-npm-info.json new file mode 100644 index 0000000..a70fb68 --- /dev/null +++ b/src/fixtures/pinpoint-npm-info.json @@ -0,0 +1,35 @@ +{ + "_id": "pinpoint", + "name": "pinpoint", + "description": "Pinpoint test fixture", + "homepage": "https://example.com/pinpoint", + "author": { + "name": "Fixture Author" + }, + "time": { + "created": "2016-01-01T00:00:00.000Z", + "modified": "2018-01-01T00:00:00.000Z" + }, + "maintainers": [ + { + "name": "fixture-maintainer" + } + ], + "dist-tags": { + "latest": "1.1.0" + }, + "versions": { + "not-a-version": { + "license": "SHOULD_NOT_BE_USED" + }, + "1.0.0": { + "license": "MIT" + }, + "1.1.0": { + "dependencies": { + "left-pad": "^1.3.0" + } + } + }, + "readme": "# Pinpoint\n\nFixture README" +} From 704cc910c1419b0a1e75b8a957d9b0ad3d705b90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 21 Apr 2026 17:32:33 +0300 Subject: [PATCH 2/3] test: improve npm fixture mocking --- src/index.test.ts | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/index.test.ts b/src/index.test.ts index c9eaf95..fa53926 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -1,11 +1,23 @@ import * as child_process from "child_process" import * as mockfs from "fs" -jest.mock("node-fetch", () => () => - Promise.resolve({ +jest.mock("node-fetch", () => (url: string) => { + const readFixture = (requestUrl: string) => { + const dep = requestUrl.split("/").pop() || "danger" + const fixturePath = `src/fixtures/${dep}-npm-info.json` + const fallbackFixturePath = "src/fixtures/danger-npm-info.json" + + try { + return JSON.parse(mockfs.readFileSync(fixturePath, "utf8")) + } catch (error) { + return JSON.parse(mockfs.readFileSync(fallbackFixturePath, "utf8")) + } + } + + return Promise.resolve({ ok: true, - json: () => Promise.resolve(JSON.parse(mockfs.readFileSync("src/fixtures/danger-npm-info.json", "utf8"))), + json: () => Promise.resolve(readFixture(url)), }) -) +}) import yarn, { _operateOnSingleDiff, @@ -155,6 +167,15 @@ describe("npm metadata", () => { const npmData = await getNPMMetadataForDep("danger") expect(_renderNPMTable({ usedInPackageJSONPaths: ["package.json"], npmData: npmData! })).toMatchSnapshot() }) + + it("Shows a version license when top-level license is missing", async () => { + expect.assertions(2) + const npmData = await getNPMMetadataForDep("pinpoint") + const rendered = _renderNPMTable({ usedInPackageJSONPaths: ["package.json"], npmData: npmData! }) + + expect(rendered).toContain("License: MIT") + expect(rendered).not.toContain("NO LICENSE FOUND") + }) }) describe("yarn metadata", () => { From 5142e5074b013dd252264f8a8549e7b29898855c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 21 Apr 2026 17:24:42 +0300 Subject: [PATCH 3/3] fix: resolve npm license from versions metadata --- src/index.ts | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 928387f..6eff0ba 100644 --- a/src/index.ts +++ b/src/index.ts @@ -171,6 +171,27 @@ export interface PartiallyRenderedNPMMetadata { readme: string } +const resolvePackageLicense = (npm: any): string | undefined => { + if (npm.license) { + return npm.license + } + + if (!npm.versions) { + return undefined + } + + const versionsWithLicenses = Object.keys(npm.versions).filter(version => semver.valid(version)).sort(semver.rcompare) + + for (const version of versionsWithLicenses) { + const versionMetadata = npm.versions[version] + if (versionMetadata && versionMetadata.license) { + return versionMetadata.license + } + } + + return undefined +} + export const getNPMMetadataForDep = async ( dep: string, npmRegistryUrl?: string, @@ -209,7 +230,7 @@ export const getNPMMetadataForDep = async ( tableDeets.push({ break: "row-break" }) // Left - const license = npm.license + const license = resolvePackageLicense(npm) if (license) { tableDeets.push({ name: "License", message: license }) } else {