pkg-stats 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +3 -0
- package/dist/bin.js +82 -0
- package/dist/chart.js +5 -0
- package/dist/index.js +2 -0
- package/dist/version.js +25 -0
- package/package.json +21 -0
package/README.md
ADDED
package/dist/bin.js
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
import { renderChart } from "./chart.js";
|
2
|
+
import { parseVersion, versionCompare } from "./version.js";
|
3
|
+
const PACKAGE_NAME = process.argv[2];
|
4
|
+
const NPM_STATS_URL = `https://api.npmjs.org/versions/${encodeURIComponent(PACKAGE_NAME)}/last-week`;
|
5
|
+
export async function bin() {
|
6
|
+
const response = await fetch(NPM_STATS_URL);
|
7
|
+
const data = await response.json();
|
8
|
+
const rawStats = Object.keys(data.downloads)
|
9
|
+
.map((versionString) => {
|
10
|
+
const version = parseVersion(versionString);
|
11
|
+
return {
|
12
|
+
...version,
|
13
|
+
downloads: data.downloads[versionString],
|
14
|
+
};
|
15
|
+
})
|
16
|
+
.sort(versionCompare);
|
17
|
+
const groupedStats = sumByMajor(rawStats);
|
18
|
+
const totalDownloads = Object.values(groupedStats).reduce((sum, version) => sum + version.downloads, 0);
|
19
|
+
console.log(`${PACKAGE_NAME} weekly downloads\n`);
|
20
|
+
console.log(`Total: ${totalDownloads.toLocaleString()}.\n`);
|
21
|
+
console.log("By version:\n");
|
22
|
+
const maxDownloads = Math.max(...groupedStats.map((v) => v.downloads));
|
23
|
+
for (const item of groupedStats) {
|
24
|
+
console.log(`${item.versionString.padStart(6)} ${renderChart(item.downloads / maxDownloads)} ${formatDownloads(item.downloads, maxDownloads).padStart(6)}`);
|
25
|
+
}
|
26
|
+
console.log(`\nGenerated on ${new Date().toISOString().slice(0, 10)} by npm-stats.`);
|
27
|
+
}
|
28
|
+
function sumByMajor(stats) {
|
29
|
+
const result = {};
|
30
|
+
for (const versionStats of stats) {
|
31
|
+
const key = `${versionStats.major}`;
|
32
|
+
const entry = result[key] ?? {
|
33
|
+
version: { major: versionStats.major },
|
34
|
+
versionString: key,
|
35
|
+
downloads: 0,
|
36
|
+
};
|
37
|
+
result[key] = entry;
|
38
|
+
entry.downloads += versionStats.downloads;
|
39
|
+
}
|
40
|
+
return Object.values(result).sort((a, b) => versionCompare(a.version, b.version));
|
41
|
+
}
|
42
|
+
function sumByMinor(stats) {
|
43
|
+
const result = {};
|
44
|
+
for (const versionStats of stats) {
|
45
|
+
const key = `${versionStats.major}.${versionStats.minor}`;
|
46
|
+
const entry = result[key] ?? {
|
47
|
+
version: { major: versionStats.major, minor: versionStats.minor },
|
48
|
+
versionString: key,
|
49
|
+
downloads: 0,
|
50
|
+
};
|
51
|
+
result[key] = entry;
|
52
|
+
entry.downloads += versionStats.downloads;
|
53
|
+
}
|
54
|
+
return Object.values(result).sort((a, b) => versionCompare(a.version, b.version));
|
55
|
+
}
|
56
|
+
function sumByPatch(stats) {
|
57
|
+
const result = {};
|
58
|
+
for (const versionStats of stats) {
|
59
|
+
const key = `${versionStats.major}.${versionStats.minor}.${versionStats.patch}`;
|
60
|
+
const entry = result[key] ?? {
|
61
|
+
version: {
|
62
|
+
major: versionStats.major,
|
63
|
+
minor: versionStats.minor,
|
64
|
+
patch: versionStats.patch,
|
65
|
+
},
|
66
|
+
versionString: key,
|
67
|
+
downloads: 0,
|
68
|
+
};
|
69
|
+
result[key] = entry;
|
70
|
+
entry.downloads += versionStats.downloads;
|
71
|
+
}
|
72
|
+
return Object.values(result).sort((a, b) => versionCompare(a.version, b.version));
|
73
|
+
}
|
74
|
+
function formatDownloads(downloads, maxDownloads) {
|
75
|
+
if (maxDownloads > 1000000) {
|
76
|
+
return `${(downloads / 1000000).toFixed(1)}M`;
|
77
|
+
}
|
78
|
+
if (maxDownloads > 1000) {
|
79
|
+
return `${(downloads / 1000).toFixed(1)}K`;
|
80
|
+
}
|
81
|
+
return downloads.toString();
|
82
|
+
}
|
package/dist/chart.js
ADDED
package/dist/index.js
ADDED
package/dist/version.js
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
export function parseVersion(version) {
|
2
|
+
const [versionCore, preRelease] = version.split("-");
|
3
|
+
const [major, minor, patch] = versionCore.split(".");
|
4
|
+
return {
|
5
|
+
major: Number(major),
|
6
|
+
minor: Number(minor),
|
7
|
+
patch: Number(patch),
|
8
|
+
preRelease,
|
9
|
+
};
|
10
|
+
}
|
11
|
+
export function versionCompare(a, b) {
|
12
|
+
if (a.major !== b.major) {
|
13
|
+
return b.major - a.major;
|
14
|
+
}
|
15
|
+
if (a.minor !== undefined && b.minor !== undefined && a.minor !== b.minor) {
|
16
|
+
return b.minor - a.minor;
|
17
|
+
}
|
18
|
+
if (a.patch !== undefined && b.patch !== undefined && a.patch !== b.patch) {
|
19
|
+
return b.patch - a.patch;
|
20
|
+
}
|
21
|
+
if (a.preRelease !== undefined && b.preRelease !== undefined) {
|
22
|
+
return a.preRelease.localeCompare(b.preRelease);
|
23
|
+
}
|
24
|
+
return 0;
|
25
|
+
}
|
package/package.json
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
{
|
2
|
+
"name": "pkg-stats",
|
3
|
+
"version": "0.0.1",
|
4
|
+
"description": "Beautiful package download stats",
|
5
|
+
"type": "module",
|
6
|
+
"main": "dist/index.js",
|
7
|
+
"files": [
|
8
|
+
"dist"
|
9
|
+
],
|
10
|
+
"scripts": {
|
11
|
+
"build": "tsc"
|
12
|
+
},
|
13
|
+
"keywords": [],
|
14
|
+
"author": "",
|
15
|
+
"license": "MIT",
|
16
|
+
"packageManager": "pnpm@9.15.0+sha512.76e2379760a4328ec4415815bcd6628dee727af3779aaa4c914e3944156c4299921a89f976381ee107d41f12cfa4b66681ca9c718f0668fa0831ed4c6d8ba56c",
|
17
|
+
"devDependencies": {
|
18
|
+
"@types/node": "^22.10.5",
|
19
|
+
"typescript": "^5.7.3"
|
20
|
+
}
|
21
|
+
}
|