Skip to content

Instantly share code, notes, and snippets.

@simonplend
Last active January 31, 2021 20:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save simonplend/1c1259cf716d373eb78507dcbc228552 to your computer and use it in GitHub Desktop.
Save simonplend/1c1259cf716d373eb78507dcbc228552 to your computer and use it in GitHub Desktop.
package-download-stats - Run in your terminal with: npx https://gist.github.com/simonplend/1c1259cf716d373eb78507dcbc228552 package-name
#! /usr/bin/env node
import { format as formatDate } from "timeago.js";
import {
getPackageDetails,
getPackageDownloadStats,
} from "./package-stats.js";
function getLatestVersion({ packageDetails }) {
return packageDetails["dist-tags"]?.latest || "Unknown";
}
function createVersionsWithDownloads({ packageDetails, packageDownloadStats }) {
const versionsWithDownloads = Object.values(packageDetails.versions).map(
({ version }) => ({
version,
downloads: packageDownloadStats[version] || 0,
published: packageDetails.time[version],
})
);
return versionsWithDownloads;
}
const packageName = process.argv[2];
const [packageDetails, packageDownloadStats] = await Promise.all([
getPackageDetails({ packageName }),
getPackageDownloadStats({ packageName }),
]);
const latestVersion = getLatestVersion({ packageDetails });
const versionsWithDownloads = createVersionsWithDownloads({
packageDetails,
packageDownloadStats,
});
const versionStats = versionsWithDownloads.sort(
(a, b) => b.downloads - a.downloads
);
const numberFormat = new Intl.NumberFormat();
console.log("");
console.log(`Package name: ${packageName}`);
console.log(`Latest version: ${latestVersion}`);
console.log("Most downloaded versions (Last 7 Days):\n");
console.log(" Version (Downloads) - Published\n");
for (let i = 0; i < 10; i++) {
const stats = versionStats[i];
console.log(
`${stats.version.padStart(8, " ")} ${`(${numberFormat.format(
stats.downloads
)})`.padStart(13, " ")} - ${formatDate(stats.published)}${
stats.version === latestVersion ? " (latest)" : ""
}`
);
}
console.log("");
console.log(`View full download stats: https://www.npmjs.com/package/${packageName}?activeTab=versions\n`)
// npm registry documentation
// https://github.com/npm/registry
// Package details including versions with dates
// https://registry.npmjs.org/$PACKAGE
// Downloads for past 7 days by package version
// https://api.npmjs.org/versions/$PACKAGE/last-week
// Web URL for package versions:
// https://www.npmjs.com/package/$PACKAGE?activeTab=versions
// npq example code requesting data:
// https://github.com/lirantal/npq/blob/master/lib/helpers/packageRepoUtils.js
// Version, Downloads (Last 7 Days), Published
import fetch from "node-fetch";
async function fetchJsonFromUrl({ url }) {
const response = await fetch(url);
if (response.ok) {
const responseBody = await response.json();
return responseBody;
} else {
throw new Error("Fetch failed");
// TODO: Error handling
}
}
export async function getPackageDetails({ packageName }) {
// data['dist-tags']['latest']
const url = `https://registry.npmjs.org/${packageName}`;
const apiResponseBody = await fetchJsonFromUrl({ url });
return apiResponseBody;
}
export async function getPackageDownloadStats({ packageName }) {
const url = `https://api.npmjs.org/versions/${packageName}/last-week`;
const apiResponseBody = await fetchJsonFromUrl({ url });
return apiResponseBody.downloads;
}
{
"name": "package-download-stats",
"version": "0.0.0",
"description": "",
"type": "module",
"bin": "./main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"node-fetch": "^2.6.1",
"timeago.js": "^4.0.2"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment