Skip to content

Commit

Permalink
feat: npmPackageVersion option (#86)
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreDemailly authored Mar 1, 2024
1 parent 4eaeb6a commit be2198a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 12 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ export interface IResultOptions {
* @default true
*/
resolveOnVersionControl?: boolean;
/**
* @description The version of the npm package (when `resolveOnNpmRegistry` only) to retrieve the scorecard for.
* @default "latest"
*/
npmPackageVersion?: string;
}
```

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
},
"homepage": "https://github.com/NodeSecure/ossf-scorecard-sdk#readme",
"devDependencies": {
"@matteo.collina/tspl": "^0.1.1",
"@nodesecure/eslint-config": "^1.9.0",
"@slimio/is": "^2.0.0",
"@types/node": "^20.11.20",
Expand Down
22 changes: 14 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,22 @@ export interface IResultOptions {
* @default true
*/
resolveOnVersionControl?: boolean;
/**
* @description The version of the npm package (when `resolveOnNpmRegistry` only) to retrieve the scorecard for.
* @default "latest"
*/
npmPackageVersion?: string;
}

async function getNpmRepository(repository: string): Promise<string> {
async function getNpmRepository(repository: string, version: string): Promise<string> {
const data = await packument(repository);
const latestVersion = data["dist-tags"].latest;
const latestVersion = data["dist-tags"].latest!;
const packageVersion = data.versions[version === "latest" ? latestVersion : version];

if (!latestVersion) {
throw new Error("Cannot find the latest version of the given repository");
if (!packageVersion) {
throw new Error(`Cannot find the version '${version}' of the given repository`);
}

const packageVersion = data.versions[latestVersion];
const homepage = packageVersion.homepage || null;
const repo = packageVersion.repository;
const repoUrl = typeof repo === "string" ? repo : repo?.url;
Expand Down Expand Up @@ -108,7 +113,8 @@ export async function result(
const {
platform = kDefaultPlatform,
resolveOnNpmRegistry = true,
resolveOnVersionControl = true
resolveOnVersionControl = true,
npmPackageVersion = "latest"
} = options;
const [owner, repo] = repository.replace("@", "").split("/");

Expand All @@ -134,7 +140,7 @@ export async function result(
}

try {
formattedRepository = await getNpmRepository(repository);
formattedRepository = await getNpmRepository(repository, npmPackageVersion);
}
catch (error) {
throw new Error(`Invalid repository, cannot find it on ${platformName} or NPM registry`, {
Expand All @@ -145,7 +151,7 @@ export async function result(
}
else if (resolveOnNpmRegistry && !resolveOnVersionControl) {
try {
formattedRepository = await getNpmRepository(repository);
formattedRepository = await getNpmRepository(repository, npmPackageVersion);
}
catch (error) {
throw new Error(`Invalid repository, cannot find it on NPM registry`, {
Expand Down
40 changes: 36 additions & 4 deletions test/result.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { after, afterEach, before, beforeEach, describe, it } from "node:test";
import { MockAgent, getGlobalDispatcher, setGlobalDispatcher, Interceptable } from "@myunisoft/httpie";
import is from "@slimio/is";
import * as npmRegistrySdk from "@nodesecure/npm-registry-sdk";
import { tspl, type Plan } from "@matteo.collina/tspl";

// Import Internal Dependencies
import * as scorecard from "../src/index.js";
Expand Down Expand Up @@ -188,14 +189,14 @@ describe("#result() FT", () => {
});

it("should throw when given a package and npm resolve is falsy", async() => {
assert.rejects(async() => scorecard.result("@unknown-package/for-sure", { resolveOnNpmRegistry: false }), {
await assert.rejects(async() => scorecard.result("@unknown-package/for-sure", { resolveOnNpmRegistry: false }), {
name: "Error",
message: "Invalid repository, cannot find it on github"
});
});

it("should throw when given a package and npm resolve is falsy (GitLab)", async() => {
assert.rejects(async() => scorecard.result("@unknown-package/for-sure", {
await assert.rejects(async() => scorecard.result("@unknown-package/for-sure", {
platform: "gitlab.com",
resolveOnNpmRegistry: false
}), {
Expand All @@ -205,21 +206,52 @@ describe("#result() FT", () => {
});

it("should throw when given an unknown npm package", async() => {
assert.rejects(async() => await scorecard.result("@unknown-package/for-sure", { resolveOnNpmRegistry: true }), {
await assert.rejects(async() => await scorecard.result("@unknown-package/for-sure", { resolveOnNpmRegistry: true }), {
name: "Error",
message: "Invalid repository, cannot find it on github or NPM registry"
});
});

it("should throw when given an unknown npm package (GitLab)", async() => {
assert.rejects(async() => await scorecard.result("@unknown-package/for-sure", {
await assert.rejects(async() => await scorecard.result("@unknown-package/for-sure", {
platform: "gitlab.com",
resolveOnNpmRegistry: true
}), {
name: "Error",
message: "Invalid repository, cannot find it on gitlab or NPM registry"
});
});

it("Should return a specific npm package ScorecardResult that does not have the repository set but has a homepage", async() => {
const result = await scorecard.result(`@topcli/prompts`, {
resolveOnVersionControl: false,
npmPackageVersion: "1.9.0"
});

assert.equal(is.plainObject(result), true);
assert.equal(result.repo.name, `github.com/TopCli/prompts`);
assert.deepStrictEqual(
Object.keys(result).sort(),
["date", "repo", "scorecard", "score", "checks"].sort()
);
});

it("Should throws when the given package version does not exists", async(testContext) => {
const tsplAssert: Plan = tspl(testContext, { plan: 3 });

// We cannot use assert.rejects to test Error.cause
try {
await scorecard.result(`@topcli/prompts`, {
resolveOnVersionControl: false,
npmPackageVersion: "99999.0.0"
});
}
catch (error) {
tsplAssert.strictEqual(error.name, "Error");
tsplAssert.strictEqual(error.message, "Invalid repository, cannot find it on NPM registry");
tsplAssert.match(error.cause.message, /^Cannot find the version '99999.0.0' of the given repository/);
}
});
});

function getPath(repository: string): string {
Expand Down

0 comments on commit be2198a

Please sign in to comment.