Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: links #190

Merged
merged 4 commits into from
Dec 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion __snapshots__/depWalker.spec.js.snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ exports['walk @slimio/is 1'] = {
]
},
"gitUrl": null,
"integrity": "c9781c55ab750e58bed9ce2560581ff4087b8c3129462543fa6fee4e717ba2a9"
"integrity": "c9781c55ab750e58bed9ce2560581ff4087b8c3129462543fa6fee4e717ba2a9",
"links": {
"npm": "https://www.npmjs.com/package/@slimio/is/v/1.5.1",
"homepage": "https://github.com/SlimIO/is#readme",
"repository": "https://github.com/SlimIO/is"
}
}
},
"vulnerabilities": [],
Expand Down
2 changes: 1 addition & 1 deletion src/depWalker.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ export async function depWalker(manifest, options = {}, logger = new Logger()) {
logger.tick(ScannerLoggerEvents.analysis.tree);

// There is no need to fetch 'N' times the npm metadata for the same package.
if (fetchedMetadataPackages.has(name)) {
if (fetchedMetadataPackages.has(name) || !current.versions[version].existOnRemoteRegistry) {
logger.tick(ScannerLoggerEvents.analysis.registry);
}
else {
Expand Down
3 changes: 2 additions & 1 deletion src/npmRegistry.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import semver from "semver";
import { packument, packumentVersion } from "@nodesecure/npm-registry-sdk";

// Import Internal Dependencies
import { parseAuthor } from "./utils/index.js";
import { parseAuthor, getLinks } from "./utils/index.js";

export async function manifestMetadata(name, version, metadata) {
try {
Expand Down Expand Up @@ -85,6 +85,7 @@ export async function packageMetadata(name, version, options) {
}
}

Object.assign(ref.versions[version], { links: getLinks(pkg.versions[version]) });
Object.assign(ref.metadata, metadata);
}
catch {
Expand Down
4 changes: 4 additions & 0 deletions src/tarball.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ export async function scanDirOrArchive(name, version, options) {
});
await timers.setImmediate();
}
else {
// Set links to an empty object because theses are generated only for NPM tarballs
Object.assign(ref, { links: {} });
}

// Read the package.json at the root of the directory or archive.
const {
Expand Down
31 changes: 31 additions & 0 deletions src/utils/getLinks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// CONSTANTS
const kVCSHosts = new Set(["github.com", "gitlab.com"]);

function getVCSRepositoryURL(link) {
try {
const url = new URL(link);
const { hostname, pathname } = url;

if (kVCSHosts.has(hostname) === false) {
return null;
}

const [owner, repo] = pathname.split("/").filter(Boolean).map((curr) => curr.replace(".git", ""));

return `https://${hostname}/${owner}/${repo}`;
}
catch {
return null;
}
}

export function getLinks(pkg) {
const homepage = pkg.homepage || null;
const repositoryUrl = pkg.repository?.url || null;

return {
npm: `https://www.npmjs.com/package/${pkg.name}/v/${pkg.version}`,
PierreDemailly marked this conversation as resolved.
Show resolved Hide resolved
homepage,
repository: getVCSRepositoryURL(homepage) ?? getVCSRepositoryURL(repositoryUrl)
};
}
1 change: 1 addition & 0 deletions src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export * from "./analyzeDependencies.js";
export * from "./booleanToFlags.js";
export * from "./addMissingVersionFlags.js";
export * from "./parseManifestAuthor.js";
export * from "./getLinks.js";

export const NPM_TOKEN = typeof process.env.NODE_SECURE_TOKEN === "string" ?
{ token: process.env.NODE_SECURE_TOKEN } :
Expand Down
29 changes: 29 additions & 0 deletions test/npmRegistry.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,33 @@ test("registry.packageMetadata", async() => {
assert.ok(ref.metadata.hasManyPublishers);
assert.ok(typeof ref.metadata.publishedCount === "number");
assert.ok(is.date(new Date(ref.metadata.lastUpdateAt)));

assert.deepEqual(ref.versions["1.5.0"].links, {
npm: "https://www.npmjs.com/package/@slimio/is/v/1.5.0",
homepage: "https://github.com/SlimIO/is#readme",
repository: "https://github.com/SlimIO/is"
});
});

test("registry.packageMetadata should find GitLab links", async() => {
const ref = {
metadata: {},
versions: {
"71.2.0": {
flags: []
}
}
};
const logger = new Logger().start("registry");

await registry.packageMetadata("@gitlab/ui", "71.2.0", {
ref,
logger
});

assert.deepEqual(ref.versions["71.2.0"].links, {
npm: "https://www.npmjs.com/package/@gitlab/ui/v/71.2.0",
homepage: "https://gitlab.com/gitlab-org/gitlab-ui#readme",
repository: "https://gitlab.com/gitlab-org/gitlab-ui"
});
});
10 changes: 10 additions & 0 deletions types/scanner.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ declare namespace Scanner {
at: string;
}

export interface DependencyLinks {
/** NPM Registry page */
npm: string;
/** Homepage URL */
homepage?: string;
/** VCS repository URL */
repository?: string;
}

export interface DependencyVersion {
/** Id of the package (useful for usedBy relation) */
id: number;
Expand Down Expand Up @@ -111,6 +120,7 @@ declare namespace Scanner {
* (Not supported on GIT dependency)
*/
integrity?: string;
links: DependencyLinks;
}

export interface Dependency {
Expand Down